我正在研究Project Euler 25。我弄清楚如何做Fibonacci而我正在使用BigInteger
。我的程序似乎正在运行一个无限循环(或者我认为)。它可能是需要很长时间还是实际上进入无限循环?有人能指出我正确的方向,所以我可以解决它吗?
import java.math.BigInteger;
public class Problem25 {
public static void main(String[] args) {
getTerm(0);
}
public static void getTerm(int start) {
BigInteger var = BigInteger.ZERO;
BigInteger var2 = BigInteger.valueOf(start);
int counter = 0;
while(true) {
BigInteger temp = var.add(var2);
var = var2;
var2 = temp;
counter++;
if(var.toString().length() > 1000) {
System.out.print(counter);
}
}
}
}
编辑:对不起的人。我想,我休息了;但感谢您的回复。
答案 0 :(得分:6)
你没有条件终止循环:
while(true) { // << always true ;P
BigInteger temp = var.add(var2);
var = var2;
var2 = temp;
counter++;
if(var.toString().length() > 1000) {
System.out.print(counter);
}
}
所以这是一个无限循环。您有两个(甚至更多)选项:
while(statement)
中指定继续循环进行另一轮的条件是什么。break;
语句来停止循环。答案 1 :(得分:3)
getTerm(0);
这不应该是getTerm(1);
吗?
另外,MByD的答案是正确的;但这也是一个关键问题。如果不改变这一点,您的程序将永远不会输出。
答案 2 :(得分:2)
1)是的,你有一个无限循环。在print()之后立即输入 break; 语句。
2)尝试寻找第一个,两位数的术语。或者三位数。很多项目欧拉问题都是很好的步骤。
3)在调试器下运行它,看看发生了什么。与2)结合得很好。
答案 3 :(得分:0)
您正在致电getTerm(0)
,因此最初var
和var2
均为零。然后,您将var2
添加到var
,这仍然为零,等等,因此var
和var2
都保持为零,您永远不会取得任何进展。我认为你的意思是getTerm(1)
,它应该正确地生成Fibonacci序列。
当然,一旦找到答案,您可能希望break
退出循环。
答案 4 :(得分:0)
为什么不打印每个值直到找到1000位数的值?不管怎样,不会有那么多,因为这些数字平均随着黄金配给而增长。
如其他地方所述,添加一个停止条件:
if(var.toString().length() > 1000) {
break;
}
答案 5 :(得分:0)
由于true
始终为true,因此除非您手动终止,否则您的循环将继续运行。请使用break;
。通过实施,我认为您应该在行System.out.print(counter)
答案 6 :(得分:0)
您可以使用:
while( !isGood() ) {
...
}
而不是
while(true) {
...
if ( isGood() ) {
break;
}
}
以下是使用上述方法的 3个解决方案(从慢到快):
1)生成所有斐波纳契数,直到满足条件。使用除以10计算数字。时间: 6625 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
// similar performance if you use an "aux" variable
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( hasLessThanSpecifiedNumberOfDigits(a, n) ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
private static boolean hasLessThanSpecifiedNumberOfDigits(BigInteger x, int n) {
return getNumberOfDigits(x) < n;
}
private static int getNumberOfDigits(BigInteger x) {
int numberOfDigits = 0 ;
while ( x.compareTo(BigInteger.ZERO) > 0 ) {
numberOfDigits++;
x = x.divide(BigInteger.TEN);
}
return numberOfDigits;
}
}
2)生成所有斐波纳契数,直到满足条件。使用字符串的长度计算数字。时间: 783 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( hasLessThanSpecifiedNumberOfDigits(a, n) ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
private static boolean hasLessThanSpecifiedNumberOfDigits(BigInteger x, int n) {
return getNumberOfDigits(x) < n;
}
private static int getNumberOfDigits(BigInteger x) {
return x.toString().length();
}
}
3)存储包含1000位数字(10 ^ 999)的最低BigInteger
。生成所有斐波纳契数,并将其与计算出的数字进行比较。时间: 19 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
final static BigInteger MIN = BigInteger.TEN.pow(N-1);
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( a.compareTo(MIN) < 0 ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
}