我的任务是找到Fibonacci列表的第一个非零成员的索引,该列表可以被这个值整除(在下面的示例中,值为:17 12 61)。所以我创建了Fibonacci序列,通过划分每个成员的序列并检查余数为零:
public static void main(String[] args) {
String stringInputValues = "17 12 61";
Scanner scan = new Scanner(stringInputValues);
int i = 0;
BigInteger value = BigInteger.ZERO;;
//start create Fibonacci numbers
int N = 9000;
BigInteger[] fibArray = new BigInteger[N + 1];
fibArray[0] = BigInteger.ZERO;
fibArray[1] = BigInteger.ONE;
for (i = 2; i <= N; i++) {
fibArray[i] = fibArray[i - 1].add(fibArray[i - 2]);
}
//end create Fibonacci numbers
while (scan.hasNext()) {
value = BigInteger.valueOf(scan.nextLong());
for (i = 0; i <= fibArray.length - 1; i++) {
if (i > 0 && fibArray[i].remainder(value) == BigInteger.ZERO) {
System.out.println(i);
break;
}
}
}
}
这不适用于分隔符的大值(数字如此之大,以至于 java.lang.OutOfMemoryError:Java堆空间),例如 233328 433156 1032566 而不是 17 12 61 我觉得我的算法太简单而且效率低下。你能帮我更有效吗? 谢谢!
答案 0 :(得分:1)
您可以使用JVM命令增加堆空间来解决您的问题。但是你的程序仍然是如此记忆力,换句话说效率非常低。如
java -Xmx256m MyProgram.java
设置256m
的最大堆空间。
我建议你,在创建斐波纳契数时检查余数。这样你就永远不会创造超出你需要的东西。并且为了确保在没有合适的分隔符时不使用太多堆,请使用停止条件。
注意:BigInteger
使用4N + 64Bytes
之类的数字来表示数字N.这是因为它在内部存储为int[]
,并且每个int都在JAVA中定义是4 Bytes
。
但第9000个斐波那契数字仍然很大......
EDIT(2):
表示第9000个Fibonacci数需要196个,因为第9000个Fibonacci数需要6248个比特来表示。由于Java中的每个int都是4字节,因此对于int []≡BigInteger数字,我们最终会得到784 + 64 = 848 Bytes
。这几乎是1KB。
答案 1 :(得分:1)
关键是一次计算一个Fibonacci数。该解决方案有一个方法,它返回可被参数整除的Fibonacci数的索引:
import java.math.BigInteger;
public class FibonacciDivider {
public static void main(String [] args) {
int [] input = {233328, 433156, 1032566};
for (int val: input) {
System.out.println("index of Fibo. num. divisible by " + val +
": " + findIndexOfFibonacciWithDivisor(BigInteger.valueOf(val)));
}
}
public static int findIndexOfFibonacciWithDivisor(BigInteger divisor) {
BigInteger a = BigInteger.ZERO;
BigInteger b = BigInteger.ONE;
int index = 0;
while (true) {
index++;
BigInteger c = b.add(a);
// the mod() method returns the remainder
if (c.mod(divisor).equals(BigInteger.ZERO)) return index;
a = b;
b = c;
}
}
}
输出(到目前为止!)是:
index of Fibo. num. divisible by 233328: 1619
index of Fibo. num. divisible by 433156: 281
它仍然在1032566上启动!
更新:index of Fibo. num. divisible by 1032566: 1548851
答案 2 :(得分:0)
第9000个斐波那契数字相当大。可能,它有足够的内存来生成9000个内存,但BigInteger
除法运算繁重,可能需要大量内存(和时间)。
介绍Iterator
而不是生成9000个数字。也许,有一些与斐波那契数字可分性相关的数学技巧。
如果您不必自己输出数字,但只想知道它是否存在,则必须使用模运算并完全避免使用BigInteger
。只需计算斐波那契数的模数。