前言
在Java中,由CPU原生提供的整型最大范围是64位 long 型整数。使用 long 型整数可以直接通过CPU指令进行计算,速度非常快。
但是如果我们使用的整数范围超过了 long 型怎么办?这个时候,就只能用软件来模拟一个大整数。 java.math.BigInteger 就是用来表示任意大小的整数。 BigInteger 内部用一个 int[] 数组来模拟一个非常大的整数。
常用的两种定义方式
BigInteger a=new BigInteger("123"); //没有参数为long的构造函数,用字符串来构造
BigInteger b=BigInteger.valueOf(123); //静态方法,返回val对应的BigInteger
四则运算
BigInteger类中定义了四则运算的方法,add,subtract,multiply,divide。对 BigInteger 做运算的时候,只能使用实例方法。
如:
a=a.add(b);
例题1
链接:https://www.luogu.com.cn/problem/P1009
AC代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
sc.close();
BigInteger ans = new BigInteger("0"),temp=new BigInteger("1");
for(int i=1;i<=n;i++) {
temp=temp.multiply(BigInteger.valueOf(i));
ans=ans.add(temp);
}
System.out.println(ans);
}
}
例题2
链接:https://www.luogu.com.cn/problem/P1591
AC代码
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt(),n;
char a;
while(t--!=0) {
n=sc.nextInt();a=(char) (sc.nextInt()+'0');
BigInteger ans=new BigInteger("1");
for(int i=1;i<=n;i++) ans=ans.multiply(BigInteger.valueOf(i));
String s=ans.toString(); //转换为String
int cnt=0;
for(int i=0;i<s.length();i++) {
if(s.charAt(i)==a) cnt++;
}
System.out.println(cnt);
}
sc.close();
}
}
例题3
题目链接:https://www.luogu.com.cn/problem/P1045
这题我想说的是,BigInteger类好是好,但是运算速度比较慢,运算量大的时候比较耗时。比如这一题就无法AC,有几个测试点运行超时(用快速幂也超时,也可能BigInteger的pow()函数内部也是快速幂实现的)。
代码
直接计算:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int p=sc.nextInt();
sc.close();
BigInteger ans=new BigInteger("2");
String s=ans.pow(p).subtract(BigInteger.valueOf(1)).toString();
System.out.println(s.length());
if(s.length()<500) { //补零
int num=500-s.length();
for(int i=0;i<num;i++) s="0"+s;
}
int start=s.length()-500;
for(int i=start;i<s.length();i++) {
System.out.print(s.charAt(i));
if((i-start+1)%50==0) System.out.println();
}
}
}
快速幂:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int p=sc.nextInt();
sc.close();
BigInteger ans=new BigInteger("1"),
temp=new BigInteger("2");
while(p>0) { //快速幂
if((p&1)==1) {
ans=ans.multiply(temp);
}
temp=temp.pow(2);
p>>=1;
}
String s=ans.subtract(BigInteger.valueOf(1)).toString();
System.out.println(s.length());
if(s.length()<500) { //补零
int num=500-s.length();
for(int i=0;i<num;i++) s="0"+s;
}
int start=s.length()-500;
for(int i=start;i<s.length();i++) {
System.out.print(s.charAt(i));
if((i-start+1)%50==0) System.out.println();
}
}
}
PS:直接用封装好的类是真的舒服…人生苦短,有现成的类为什么不用呢。用C++的话自己写比较麻烦。