前几天与我同学说起兔子问题(斐波那契数列),他问我第10000个月的兔子数量是多少?然后我就用JAVA开始算。
首先用int类型方法
[Java] 纯文本查看 复制代码 public class Tuzi1 {
public static void main(String[] args) {
int month = 46;
long start = System.currentTimeMillis();
System.out.println("第"+month+"个月兔子总数为"+fun(month));
long end = System.currentTimeMillis();
System.out.println("程序运行时间" + (end-start) + "毫秒");
}
private static int fun(int n){
if(n==1 || n==2)
return 1;
else
return fun(n-1)+fun(n-2);
}
}
但是int长度不够。
当month=46是正数1836311903 month=47是兔子的总数量为-1323752223;表示int数据类型(-2147483648~2147483647)范围越界。第47个月的数量是2971215073;
然后换long类型,这时又出了一个新问题,在程序中用的是fun()方法,使用了递归,当month>50时,程序运行时间变长,所以把代码改为以下:
[AppleScript] 纯文本查看 复制代码 public class Tuzi2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
long month=1406;
long i1=1;//第一个月兔子为一对
long i2=1;//第二个月兔子为一对
long i=0;//代表前一个月兔子的对数
long sum=0; //兔子的总数
for(long j=3;j<=month;j++){
i=i2;//当J=3时,前一个月即为第二个月,故将i2的值给i
i2=i+i1;
i1=i;
sum=sum+i2+2;
}
System.out.println("兔子的总数量为"+sum*2);
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
但是long类型只能计算到month=88(兔子数量5760134388741632578),超过88,又超范围了,改为double类型,但是double
有一个缺点,大的数字用幂表示,只能精确到小数点后面16位,即使是这样也只能计算到month=1406(兔子数量1.6074684786574634E294)。
这时我一脸蒙逼的样子,没有类型可用了,这时还没网,用手机搜了一下,找到了BigInteger。
BigInteger介绍:不可变的任意精度的整数。所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型)。
BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。
另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
1.BigInteger属于java.math.BigInteger,包,因此在每次使用前都要导包。使用时不要忘记导包。
2.其构造方法有很多,但现在我用到的是时:
1).加法: BigInteger add(BigInteger val)
返回其值为 (this + val) 的 BigInteger
2).常量:BigInteger.ONE,常量1.
3).数组:BigInteger[];
3.另外说明BigInteger的数学运算。
减法:subtract(BigInteger val)返回其值为 (this - val) 的 BigInteger。
乘法:multiply(BigInteger val)返回其值为 (this * val) 的 BigInteger。
除法:divide(BigInteger val)返回其值为 (this / val) 的 BigInteger。
取模:BigInteger remainder(BigInteger val)返回其值为 (this % val) 的 BigInteger。
注意:其内容进行数学运算时不能直接使用数学运算符进行运算,必须使用其内部方法。
而且其操作数也必须为BigInteger型。如:two.add(2)就是一种错误的操作,因为2没有变为BigInteger型。
新代码
[Java] 纯文本查看 复制代码 import java.math.BigInteger;
public class Tuzi3 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
//创建数组
int month=1407;
BigInteger[] integers = new BigInteger[month];
//初始化前两个数字
integers[0] = BigInteger.ONE;
integers[1] = BigInteger.ONE;
for (int i = 2; i < month; i++)
integers = integers[i - 1].add(integers[i - 2]);
//打印数组
BigInteger sum =integers[0];
for (int i = 0; i < integers.length; i++)
sum =integers;
System.out.println("第"+ month +"个月兔子数量:" + sum);
long end=System.currentTimeMillis();
System.out.println("程序耗时 "+(end-start)+" 毫秒");
}
}
使用BigInteger,不但能计算出month=10000(用时22毫秒),就是month=20000(用时65毫秒)也可以,因为数据太长,就不写了。
|