`
zwhc
  • 浏览: 266287 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

压缩圆周率

阅读更多
压缩圆周率
圆周率是无穷尽的。取前面的100万位,玩玩压缩。

目标:
1、生成的文件最小。
2、程序可以根据生成的文件,打印出圆周率前面的100万位。

第一考虑的是:使用四位编码,那么,每个字节可以存储两个数字。这样,可以压缩一半。

查看圆周率小数点后一百万位
http://pi.911cha.com/3.1415926.txt

下午写了点代码对数据进行一些分析:

package test;

import java.io.InputStream;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;

public class YsYzl {
	
	private static void test01()
	{
		for(int i=0; i<1024; i++)
		{
			String s = Integer.toBinaryString(i);
			int len = s.length();
			for(int j=len; j<10; j++)
			{
				s = '0' + s;
			}
			System.out.println(s + " " + i);
		}
	}
	
	private static void test02()
	{
		for(int i=0; i<256; i++)
		{
			String s = Integer.toBinaryString(i);
			int len = s.length();
			for(int j=len; j<8; j++)
			{
				s = '0' + s;
			}
			System.out.println(s + " " + i);
		}
	}
	
	/**
	 * 从文件中获取圆周率
	 * @throws Exception
	 */
	private static void getYzl() throws Exception
	{
		long begin = System.currentTimeMillis();
		//System.out.println(System.currentTimeMillis());
		InputStream is = YsYzl.class.getResourceAsStream("yzl.txt");
		int buf = 0;
		StringBuffer sb = new StringBuffer(); 
		while(true)
		{
			buf = is.read();
			if(buf==-1)
			{
				break;
			}
			if(buf!=13 && buf!=10)
			{
				sb.append((char)buf);
			}
		}
		sYzl = sb.toString();
		is.close();
		System.out.println(System.currentTimeMillis()-begin);
	}
	
	/**
	 * 打印出圆周率。
	 */
	private static void print()
	{
		System.out.println(sYzl.length());
		//System.out.println(sYzl); //不能通过本方法打印出圆周率
		for(int i=0; i<10000; i++)
		//for(int i=0; i<10; i++)
		{
			for(int j=0; j<100; j++)
			{
				System.out.print(sYzl.charAt(i*100 + j));
			}
			System.out.println();
		}
	}
	
	private static int doStatistics(String str)
	{
		int count = 0;
		int fromIndex = 0;
		while(true)
		{
			int idx = sYzl.indexOf(str, fromIndex);
			if(idx==-1)
			{
				break;
			}
			count++;
			fromIndex = idx+str.length();
		}
		//System.out.println(str + ":" + count);
		return count;
	}
	
	/**
	 * 统计,计算长串的数量
	 * 比如,有如下五个数据 
000:871
001:973
002:1021
003:989
004:989

	将存储为 
1021
  002
989
  003
  004
973
  001
871    
  000
	 */
//	private static void statistics()
//	{
//		int count = 0;
//		String str = "";
//		for(int i=0; i<1000; i++)
//		{
//			if(i<10)
//			{
//				str = "00" + i;
//			}
//			else if(i<100)
//			{
//				str = "0" + i;
//			}
//			else
//			{
//				str = "" + i;
//			}
//			
//			count = doStatistics(str);
//			Vector<String> vct = tmCount.get(count);
//			if(vct==null)
//			{
//				vct = new Vector<String>();
//				tmCount.put(count, vct);
//			}
//			vct.add(str);
//		}
//	}

//	private static void statistics()
//	{
//		int count = 0;
//		String str = "";
//		for(int i=0; i<10000; i++)
//		{
//			if(i<10)
//			{
//				str = "000" + i;
//			}
//			else if(i<100)
//			{
//				str = "00" + i;
//			}
//			else if(i<1000)
//			{
//				str = "0" + i;
//			}
//			else
//			{
//				str = "" + i;
//			}
//			
//			count = doStatistics(str);
//			Vector<String> vct = tmCount.get(count);
//			if(vct==null)
//			{
//				vct = new Vector<String>();
//				tmCount.put(count, vct);
//			}
//			vct.add(str);
//			
////			if((i/100)*100==i)
////			{
////				System.out.println("stat:" + i);
////				//System.out.flush();
////			}
//		}
//		
//		System.out.println(tmCount.lastKey());
//	}

	private static void statistics()
	{
		int count = 0;
		String str = "";
		for(int i=0; i<10; i++)
		{
//			if(i<10)
//			{
//				str = "0" + i;
//			}
//			else
//			{
//				str = "" + i;
//			}
			
			str = "" + i;
			
			count = doStatistics(str);
			Vector<String> vct = tmCount.get(count);
			if(vct==null)
			{
				vct = new Vector<String>();
				tmCount.put(count, vct);
			}
			vct.add(str);
			
//			if((i/100)*100==i)
//			{
//				System.out.println("stat:" + i);
//				//System.out.flush();
//			}
		}
		
		System.out.println(tmCount.lastKey());
	}
	
	
	private static void printCount()
	{
		System.out.println("*************printCount");
		//Set<Integer> set = tmCount.keySet().iterator();
		
		Iterator<Integer> keys = tmCount.keySet().iterator();
		while(keys.hasNext())
		{
			int key = keys.next();
			System.out.print(key + ":");
			Vector<String> vct = tmCount.get(key);
			Iterator<String> values = vct.iterator();
			while(values.hasNext())
			{
				System.out.print(values.next());
				System.out.print(",");
			}
			System.out.println();
		}
	}
	
	public static void main(String[] args) {
		try {
			//test01();
			getYzl();
			//print();
			statistics();
			printCount();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static String sYzl; //圆周率的值
	public static TreeMap<Integer, Vector<String>> tmCount = new TreeMap<Integer, Vector<String>>();

}



一些统计数据:

统计数字出现的次数:
格式:
99548:6 表示,数字 6 出现 99548 次。

每个数字出现次数
99548:6,
99758:1,
99800:7,
99959:0,
99985:8,
100026:2,
100106:9,
100229:3,
100230:4,
100359:5,

两位的数字出现的次数,前若干个
10110:21,
10112:76,
10147:60,
10148:19,
10173:08,
10188:35,
10193:46,
10194:54,
10224:27,
10239:94,

三位的数字出现的次数,前若干个
133:0714,6490,
134:0735,5452,
135:0275,6477,
136:7801,
137:3573,
138:4710,9944,
141:3391,

四位的数字出现的次数,前若干个
1073:244,270,
1075:027,
1076:944,
1077:195,
1078:136,735,
1086:934,
1089:160,453,
1092:654,


0
0
分享到:
评论
1 楼 zwhc 2010-08-02  
开发我们自己的“Super PI”,支持的进来

http://topic.csdn.net/u/20071218/10/57e71e72-8239-4b31-8c93-0fd0e3d42f9c.html


计算圆周率是一个热门话题, 好多人都编写了计算圆周率的程序。其中包括 Super PI,super PI 使用了最为常用的AGM算法,这个算法并不难,仅需要实现大数的乘法,倒数,平方根,除法(可用倒数和乘法算法实现)。值得注意的是,Super PI并不是一个最快的算法。π calculation programs 给出了好多个圆周率计算器一些信息,包括作者,运行速度,算法,来源。可见(http://myownlittleworld.com/miscellaneous/computers/pilargetable.html)

  在这些程序中,由 Hanhong Xue 写的使用 GMP 库的程序是最快的。在Core 2 3.0G 的电脑上 计算100万位圆周率 仅需1.68秒。关于这个程序的一些信息请参阅:Computing billions of π digits using GMP (http://gmplib.org/pi-with-gmp.html)
 
  关于 计算圆周率 的一些知识,我最早见于 http://www.jason314.com。 时间大约是:2000年左右,关于计算圆周率的算法可从这个网站上得到一些帮助。

  我曾在编程爱好者网站上讨论过计算圆周率的算法,请参阅 http://www.programfan.com/club/post-223320-3.html

相关推荐

Global site tag (gtag.js) - Google Analytics