java中大数据类在ACM中的应用

ACM/ICPC竞赛中会遇到许多高精度计算的题目,比如两个大整数相加(1111111111111111111111111111111111111111 + 22222343259435894305894301243)。如果我们还采用普通类型比如long long来存储这些值,是装不下这么大的值的了。

我们通常的做法是以字符串的形式保存值,然后编程模拟人的计算过程,例如

X = “111”;

Y = “999”;

X + Y用如下方法计算:

       1     1     1

+     9     9     9

————————

       10    10    10

然后再逐一进位得到“1110”。

减法,乘法,除法都是基于字符串模拟的基础之上的。

同时Java类库提供了高精度运算的类java.math.BigInteger和java.math.BigDecimal,这样我们在比赛时就可以使用这两个类完成高精度计算的要求。

BigInteger用于任意精度的整数的运算:

例:

BigInteger x = new BigInteger(“11111111111111111111111111111111111111”);

BigInteger y = new BigInteger(“22222343259435894305894301243”);

System.out.println(x .add(y));

BigInteger类:

abs()       返回其值是此BigInteger的绝对值的BigInteger。

compareTo(BigInteger val) 将此BigInteger与指定的BigInteger进行比较。

divide(BigInteger val)  返回其值为 (this / val) 的BigInteger。

pow(int exponent)  返回其值为 (thisexponent) 的BigInteger。

multiply(BigInteger val)  返回其值为 (this * val) 的BigInteger。

gcd(BigInteger val) 返回一个 BigInteger,其值是 abs(this) 和 abs(val) 的最大公约数。

subtract(BigInteger val) 返回其值为 (this - val) 的 BigInteger。

BigDecimal类:

BigDecimal(String val) 
          将 BigDecimal 的字符串表示形式转换为 BigDecimal。

abs() 
          返回 BigDecimal,其值为此 BigDecimal 的绝对值,其标度为 this.scale()。

add(BigDecimal augend) 
          返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。

compareTo(BigDecimal val) 
          将此 BigDecimal 与指定的 BigDecimal 比较。

divide(BigDecimal divisor, int scale, int roundingMode) 
          返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。

       RoundingMode

CEILING 
          向正无限大方向舍入的舍入模式。

DOWN 
          向零方向舍入的舍入模式。

FLOOR 
          向负无限大方向舍入的舍入模式。

HALF_DOWN 
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。

HALF_EVEN 
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

HALF_UP 
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。

UNNECESSARY 
          用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。

UP 
          远离零方向舍入的舍入模式。

setScale(int newScale, RoundingMode roundingMode) 
          返回 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,以维护其总值。

subtract(BigDecimal subtrahend) 
          返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。

divide(BigDecimal divisor, RoundingMode roundingMode) 
          返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()。

更多的函数请参考javaAPI文档。 

[java]  view plain copy
  1. 下面给出poj1131代码:   
  2.   
  3. import java.util.*;   
  4. import java.io.*;   
  5. import java.math.*;   
  6.   
  7. public class Main_1131 {   
  8.     public static void main(String[] args) {   
  9.         Scanner in = new Scanner(System.in);   
  10.         String str, ors;   
  11.         BigDecimal x, y, z;   
  12.         while (in.hasNext()) {   
  13.             ors = in.next();   
  14.             str = ors.substring(ors.indexOf(".") + 1, ors.length());   
  15.             z = new BigDecimal(0);   
  16.             y = new BigDecimal(1);   
  17.             for (int i = 0; i < str.length(); ++i) {   
  18.                 x = new BigDecimal(str.charAt(i) - '0');   
  19.                 y = y.multiply(new BigDecimal(8));   
  20.                 x = x.divide(y, str.length() * 3, RoundingMode.HALF_UP);   
  21.                 z = z.add(x);   
  22.             }   
  23.             System.out.println(ors + " [8] = " + z + " [10]");   
  24.         }   
  25.     }   
  26. }  
  27.   
  28. --------------------------------------------------------------------------------  

ACM中java的使用

 

这里指的java速成,只限于java语法,包括输入输出,运算处理,字符串和高精度的处理,进制之间的转换等,能解决OJ上的一些高精度题目。

[java]  view plain copy
  1. 1. 输入:  
  2.   
  3. 格式为:Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  4.   
  5. 例程:  
  6.   
  7. import java.io.*;  
  8.   
  9. import java.math.*;  
  10.   
  11. import java.util.*;  
  12.   
  13. import java.text.*;  
  14.   
  15. public class Main  
  16.   
  17. {  
  18.   
  19.     public static void main(String[] args)   
  20.   
  21.     {  
  22.   
  23.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  24.   
  25.         int a; double b; BigInteger c; String st;  
  26.   
  27.         a = cin.nextInt(); b = cin.nextDouble(); c = cin.nextBigInteger(); d = cin.nextLine(); // 每种类型都有相应的输入函数.  
  28.   
  29.     }  
  30.   
  31. }  
  32.   
  33.    
  34.   
  35. 2. 输出  
  36.   
  37. 函数:System.out.print(); System.out.println(); System.out.printf();  
  38.   
  39. System.out.print(); // cout << …;  
  40.   
  41. System.out.println(); // cout << … << endl;  
  42.   
  43. System.out.printf(); // 与C中的printf用法类似.  
  44.   
  45. 例程:  
  46.   
  47. import java.io.*;  
  48.   
  49. import java.math.*;  
  50.   
  51. import java.util.*;  
  52.   
  53. import java.text.*;  
  54.   
  55. public class Main  
  56.   
  57. {  
  58.   
  59.     public static void main(String[] args)   
  60.   
  61.     {  
  62.   
  63.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  64.   
  65.         int a; double b;  
  66.   
  67.         a = 12345; b = 1.234567;  
  68.   
  69.         System.out.println(a + " " + b);  
  70.   
  71.         System.out.printf("%d %10.5f\n", a, b); // 输入b为字宽为10,右对齐,保留小数点后5位,四舍五入.  
  72.   
  73.     }  
  74.   
  75. }  
  76.   
  77. 规格化的输出:  
  78.   
  79. 函数:  
  80.   
  81. // 这里0指一位数字,#指除0以外的数字(如果是0,则不显示),四舍五入.  
  82.   
  83.     DecimalFormat fd = new DecimalFormat("#.00#");  
  84.   
  85.     DecimalFormat gd = new DecimalFormat("0.000");  
  86.   
  87.     System.out.println("x =" + fd.format(x));  
  88.   
  89.     System.out.println("x =" + gd.format(x));  
  90.   
  91.    
  92.   
  93. 3. 字符串处理  
  94.   
  95. java中字符串String是不可以修改的,要修改只能转换为字符数组.  
  96.   
  97. 例程:  
  98.   
  99. import java.io.*;  
  100.   
  101. import java.math.*;  
  102.   
  103. import java.util.*;  
  104.   
  105. import java.text.*;  
  106.   
  107. public class Main  
  108.   
  109. {  
  110.   
  111.     public static void main(String[] args)   
  112.   
  113.     {  
  114.   
  115.         int i;  
  116.   
  117.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  118.   
  119.         String st = "abcdefg";  
  120.   
  121.         System.out.println(st.charAt(0)); // st.charAt(i)就相当于st[i].  
  122.   
  123.         char [] ch;  
  124.   
  125.         ch = st.toCharArray(); // 字符串转换为字符数组.  
  126.   
  127.         for (i = 0; i < ch.length; i++) ch[i] += 1;  
  128.   
  129.         System.out.println(ch); // 输入为“bcdefgh”.  
  130.   
  131. if (st.startsWith("a")) // 如果字符串以'0'开头.  
  132.   
  133.         {  
  134.   
  135.             st = st.substring(1); // 则从第1位开始copy(开头为第0位).  
  136.   
  137.         }  
  138.   
  139.     }  
  140.   
  141. }  
  142.   
  143.    
  144.   
  145. 4. 高精度  
  146.   
  147. BigInteger和BigDecimal可以说是acmer选择java的首要原因。  
  148.   
  149. 函数:add, subtract, divide, mod, compareTo等,其中加减乘除模都要求是BigInteger(BigDecimal)和BigInteger(BigDecimal)之间的运算,所以需要把int(double)类型转换为BigInteger(BigDecimal),用函数BigInteger.valueOf().  
  150.   
  151. 例程:  
  152.   
  153. import java.io.*;  
  154.   
  155. import java.math.*;  
  156.   
  157. import java.util.*;  
  158.   
  159. import java.text.*;  
  160.   
  161. public class Main  
  162.   
  163. {  
  164.   
  165.     public static void main(String[] args)   
  166.   
  167.     {  
  168.   
  169.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  170.   
  171.         int a = 123, b = 456, c = 7890;  
  172.   
  173.         BigInteger x, y, z, ans;  
  174.   
  175.         x = BigInteger.valueOf(a); y = BigInteger.valueOf(b); z = BigInteger.valueOf(c);  
  176.   
  177.         ans = x.add(y); System.out.println(ans);  
  178.   
  179.         ans = z.divide(y); System.out.println(ans);  
  180.   
  181.         ans = x.mod(z); System.out.println(ans);  
  182.   
  183.         if (ans.compareTo(x) == 0) System.out.println("1");  
  184.   
  185.     }  
  186.   
  187. }  
  188.   
  189.    
  190.   
  191. 5. 进制转换  
  192.   
  193. java很强大的一个功能。  
  194.   
  195. 函数:  
  196.   
  197. String st = Integer.toString(num, base); // 把num当做10进制的数转成base进制的st(base <= 35).  
  198.   
  199. int num = Integer.parseInt(st, base); // 把st当做base进制,转成10进制的int(parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).     
  200.   
  201. BigInter m = new BigInteger(st, base); // st是字符串,base是st的进制.  
  202.   
  203. //Added by abilitytao  
  204.   
  205. 1.如果要将一个大数以2进制形式读入 可以使用cin.nextBigInteger(2);   
  206.   
  207. 当然也可以使用其他进制方式读入;  
  208.   
  209. 2.如果要将一个大数转换成其他进制形式的字符串 使用cin.toString(2);//将它转换成2进制表示的字符串  
  210.   
  211. 例程:POJ 2305  
  212.   
  213.    
  214.   
  215. import java.io.*;  
  216.   
  217. import java.util.*;  
  218.   
  219. import java.math.*;  
  220.   
  221. public class Main  
  222.   
  223. {  
  224.   
  225.     public static void main(String[] args)  
  226.   
  227.     {  
  228.   
  229.         int b;  
  230.   
  231.         BigInteger p,m,ans;  
  232.   
  233.         String str ;  
  234.   
  235.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  236.   
  237.         while(cin.hasNext())  
  238.   
  239.         {  
  240.   
  241.             b=cin.nextInt();  
  242.   
  243.             if(b==0)  
  244.   
  245.                 break;  
  246.   
  247.             p=cin.nextBigInteger(b);  
  248.   
  249.             m=cin.nextBigInteger(b);  
  250.   
  251.             ans=p.mod(m);  
  252.   
  253.             str=ans.toString(b);  
  254.   
  255.             System.out.println(str);  
  256.   
  257.         }  
  258.   
  259.     }  
  260.   
  261. }  
  262.   
  263. //End by abilitytao  
  264.   
  265.    
  266.   
  267. 6. 排序  
  268.   
  269. 函数:Arrays.sort();至于怎么排序结构体,像C++里写个cmp的方法,在java还不太清楚,希望有人指点下~~  
  270.   
  271. 例程:  
  272.   
  273. import java.io.*;  
  274.   
  275. import java.math.*;  
  276.   
  277. import java.util.*;  
  278.   
  279. import java.text.*;  
  280.   
  281. public class Main  
  282.   
  283. {  
  284.   
  285.     public static void main(String[] args)   
  286.   
  287.     {  
  288.   
  289.         Scanner cin = new Scanner (new BufferedInputStream(System.in));  
  290.   
  291.         int n = cin.nextInt();  
  292.   
  293.         int a[] = new int [n];  
  294.   
  295.         for (int i = 0; i < n; i++) a[i] = cin.nextInt();  
  296.   
  297.         Arrays.sort(a);  
  298.   
  299.         for (int i = 0; i < n; i++) System.out.print(a[i] + " ");  
  300.   
  301.     }  
  302.   
  303. }  
  304.   
  305.    

7. POJ高精度题目汇总:

POJ 1131 1205 1220 1405 1503 1604 1894 2084 2305 2325 2389 2413 3101 3199

 

转自:http://hi.baidu.com/czyuan_acm/blog/item/d0bf7a439d90d21b72f05d69.html

 

acm中Java的应用

Chapter I.

Java的优缺点各种书上都有,这里只说说用Java做ACM-ICPC的特点:

(1) 最明显的好处是,学会Java,可以参加Java Challenge    :)

(2) 对于熟悉C/C++的程序员来说,Java 并不难学,找本书,一两周业余时间就可以搞定了。当然,这里只是指一般编程,想熟悉所有的Java库还是需要些时间的。

      事实上,Java 只相当于C++的一个改进版,所有的语法都几乎是C++的,很少有变动。

(3) 在一般比赛中,Java程序会有额外的时间和空间,而实际上经过实验,在执行计算密集任务的时候Java并不比C/C++慢多少,只是IO操作较慢而已。

(4) Java 简单而功能强大,有些东西用Java实现起来更为方便,比如高精度。

(5) 用Java不易犯细微的错误,比如C/C++中的指针, “if (n = m) ... ” 等

(6) 目前来看Eclipse已成基本配置,写Java程序反而比C/C++更方便调试。在具体竞赛时也算多一种选择。

(7) 学会Java对以后工作有好处。现在国外很多地方会Java的人比会C/C++的人多。

(8) 会Java可以使你看起来更像偶蹄类动物(牛)      hoho~ 

[java]  view plain copy
  1. Chapter II.   
  2.   
  3. 下面说一下ACM-ICPC队员初用Java编程所遇到的一些问题:   
  4.   
  5. 1. 基本输入输出:   
  6.   
  7. (1)   
  8.   
  9. JDK 1.5.0 新增的Scanner类为输入提供了良好的基础,简直就是为ACM-ICPC而设的。   
  10.   
  11. 一般用法为:   
  12.   
  13. import java.io.*   
  14.   
  15. import java.util.*   
  16.   
  17. public class Main   
  18.   
  19. {   
  20.   
  21.       public static void main(String args[])   
  22.   
  23.       {   
  24.   
  25.           Scanner cin = new Scanner(new BufferedInputStream(System.in));   
  26.   
  27.           ...   
  28.   
  29.       }   
  30.   
  31. }   
  32.   
  33. 当然也可以直接 Scanner cin = new Scanner(System.in);   
  34.   
  35. 只是加Buffer可能会快一些   
  36.   
  37. (2)   
  38.   
  39. 读一个整数:    int n = cin.nextInt();          相当于    scanf("%d", &n);    或 cin >> n;   
  40.   
  41. 读一个字符串:String s = cin.next();          相当于    scanf("%s", s);      或 cin >> s;   
  42.   
  43. 读一个浮点数:double t = cin.nextDouble();    相当于    scanf("%lf", &t); 或 cin >> t;   
  44.   
  45. 读一整行:      String s = cin.nextLine();      相当于    gets(s);            或 cin.getline(...);   
  46.   
  47. 判断是否有下一个输入可以用 cin.hasNext() 或 cin.hasNextInt() 或 cin.hasNextDouble() 等,具体见 TOJ 1001 例程。   
  48.   
  49. (3)   
  50.   
  51. 输出一般可以直接用 System.out.print() 和 System.out.println(),前者不输出换行,而后者输出。   
  52.   
  53. 比如:System.out.println(n);    // n 为 int 型   
  54.   
  55. 同一行输出多个整数可以用   
  56.   
  57.       System.out.println(new Integer(n).toString() + " " + new Integer(m).toString());   
  58.   
  59. 也可重新定义:   
  60.   
  61. static PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));   
  62.   
  63. cout.println(n);   
  64.   
  65. (4)   
  66.   
  67. 对于输出浮点数保留几位小数的问题,可以使用DecimalFormat类,   
  68.   
  69. import java.text.*;   
  70.   
  71. DecimalFormat f = new DecimalFormat("#.00#");   
  72.   
  73. DecimalFormat g = new DecimalFormat("0.000");   
  74.   
  75. double a = 123.45678, b = 0.12;   
  76.   
  77. System.out.println(f.format(a));   
  78.   
  79. System.out.println(f.format(b));   
  80.   
  81. System.out.println(g.format(b));   
  82.   
  83. 这里0指一位数字,#指除0以外的数字。   
  84.   
  85.    
  86.   
  87. 2. 大数字   
  88.   
  89. BigInteger 和 BigDecimal 是在java.math包中已有的类,前者表示整数,后者表示浮点数   
  90.   
  91. 用法:   
  92.   
  93. 不能直接用符号如+、-来使用大数字,例如:   
  94.   
  95. (import java.math.*)    // 需要引入 java.math 包   
  96.   
  97. BigInteger a = BigInteger.valueOf(100);   
  98.   
  99. BigInteger b = BigInteger.valueOf(50);   
  100.   
  101. BigInteger c = a.add(b)    // c = a + b;   
  102.   
  103. 主要有以下方法可以使用:   
  104.   
  105. BigInteger add(BigInteger other)   
  106.   
  107. BigInteger subtract(BigInteger other)   
  108.   
  109. BigInteger multiply(BigInteger other)   
  110.   
  111. BigInteger divide(BigInteger other)   
  112.   
  113. BigInteger mod(BigInteger other)   
  114.   
  115. int compareTo(BigInteger other)   
  116.   
  117. static BigInteger valueOf(long x)   
  118.   
  119. 输出大数字时直接使用 System.out.println(a) 即可。   
  120.   
  121.    
  122.   
  123. 3. 字符串   
  124.   
  125. String 类用来存储字符串,可以用charAt方法来取出其中某一字节,计数从0开始:   
  126.   
  127. String a = "Hello";      // a.charAt(1) = ’e’   
  128.   
  129. 用substring方法可得到子串,如上例   
  130.   
  131. System.out.println(a.substring(04))      // output "Hell"   
  132.   
  133. 注意第2个参数位置上的字符不包括进来。这样做使得 s.substring(a, b) 总是有 b-a个字符。   
  134.   
  135. 字符串连接可以直接用 + 号,如   
  136.   
  137. String a = "Hello";   
  138.   
  139. String b = "world";   
  140.   
  141. System.out.println(a + ", " + b + "!");      // output "Hello, world!"   
  142.   
  143. 如想直接将字符串中的某字节改变,可以使用另外的StringBuffer类。   
  144.   
  145.    
  146.   
  147. 4. 调用递归(或其他动态方法)   
  148.   
  149. 在主类中 main 方法必须是 public static void 的,在 main 中调用非static类时会有警告信息,   
  150.   
  151. 可以先建立对象,然后通过对象调用方法:   
  152.   
  153. public class Main   
  154.   
  155. {   
  156.   
  157.       ...   
  158.   
  159.       void dfs(int a)   
  160.   
  161.       {   
  162.   
  163.           if (...) return;   
  164.   
  165.           ...   
  166.   
  167.           dfs(a+1);   
  168.   
  169.       }   
  170.   
  171.        
  172.   
  173.       public static void main(String args[])   
  174.   
  175.       {   
  176.   
  177.           ...   
  178.   
  179.           Main e = new Main();   
  180.   
  181.           e.dfs(0);   
  182.   
  183.           ...   
  184.   
  185.       }   
  186.   
  187. }   
  188.   
  189. 5. 其他注意的事项   
  190.   
  191. (1) Java 是面向对象的语言,思考方法需要变换一下,里面的函数统称为方法,不要搞错。   
  192.   
  193. (2) Java 里的数组有些变动,多维数组的内部其实都是指针,所以Java不支持fill多维数组。   
  194.   
  195.       数组定义后必须初始化,如 int[] a = new int[100];   
  196.   
  197. (3) 布尔类型为 boolean,只有truefalse二值,在 if (...) / while (...) 等语句的条件中必须为boolean类型。   
  198.   
  199.       在C/C++中的 if (n % 2) ... 在Java中无法编译通过。   
  200.   
  201. (4) 下面在java.util包里Arrays类的几个方法可替代C/C++里的memset、qsort/sort 和 bsearch:   
  202.   
  203. Arrays.fill()   
  204.   
  205. Arrays.sort()   
  206.   
  207. Arrays.binarySearch()    
  208.   
  209. 转自:http://hi.baidu.com/oak_wesley/blog/item/35839200fd9dc10e1d9583de.html  
  210.   
  211.   
  212. --------------------------------------------------------------------------------  
  213.   
  214. //PKU 1001  
  215. //计算R^N,R为浮点数  
  216. /* BigInteger/BigDecimal 常用方法(所有方法均为1个参数) 
  217. add()加  subtract()减  multiply()乘  divide()除 
  218. abs()绝对值  max()最大值  min()最小值 
  219. compareTo()比较大小  toString()转为字符串 
  220.  
  221.  
  222. 仅BigInteger: 
  223. mod()取余  gcd()求最大公约数 
  224. and()求与  or()求或  not()求反  xor()求异或 
  225. */  
  226.   
  227.   
  228. import java.io.*;  
  229. import java.math.*;  
  230. import java.util.*;  
  231. import java.text.*;  
  232.   
  233.   
  234. public class Main  
  235. {  
  236.     public static void main(String[] args)  
  237.     {  
  238.         Scanner cin=new Scanner(System.in);  
  239.         while(cin.hasNext())  
  240.         {  
  241.             BigDecimal x=cin.nextBigDecimal();  
  242.             BigDecimal y=BigDecimal.valueOf(1.0);  
  243.             int n=cin.nextInt();  
  244.             for(int i=1;i<=n;i++)  
  245.                 y=y.multiply(x);  
  246.             String out=new String(y.toPlainString());  
  247.             boolean flag=false;  
  248.             int q=out.length()-1;  
  249.             //去掉前导零  
  250.             while(out.charAt(q)=='0') q--;  
  251.             if (out.charAt(q)=='.') q--;  
  252.             int p=0;  
  253.             //去掉小数点后多余的零  
  254.             while(out.charAt(p)=='0') p++;  
  255.             for(int i=p;i<=q;i++)  
  256.                 System.out.print(out.charAt(i));  
  257.             System.out.println();  
  258.         }  
  259.     }  
  260. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值