我制作了这段代码..而且我需要充分利用它......我真的需要计算斐波那契数字的最佳表现..请帮助...
我已经阅读了一些此类计算的代码,我认为我得到了最好的...
对我来说,这是对... .. plz ..
ps:我真的需要BigInteger ..我会计算出庞大数字的Fibonacci
ps2:我用这个算法计算了一些大数字,我得到了很好的响应时间..但我需要知道它是否会更好
ps3:要运行此代码,您需要使用此VM参数-Xss16384k
(StackSize)
public class Fibonacci {
private static BigInteger[] fibTmp = { BigInteger.valueOf(0), BigInteger.valueOf(1) };
public static BigInteger fibonacci(long v) {
BigInteger fib = BigInteger.valueOf(0);
if (v == 1) {
fib = BigInteger.valueOf(1);
} else if (v == 0) {
fib = BigInteger.valueOf(0);
} else {
BigInteger v1 = fibonacci(v - 1);
BigInteger v2 = fibTmp[(int) (v - 2)];
fib = v1.add(v2);
}
synchronized (fibTmp) {
if (fibTmp.length - 1 < v)
fibTmp = Arrays.copyOf(fibTmp, (int) (v + 10));
fibTmp[(int) v] = fib;
}
return fib;
}
}
答案 0 :(得分:7)
是的,有更好的方法。在给定正整数作为输入的情况下,这是一种log(n)
测试且非常有效的方法,用于以任意精度计算Fibonacci的值。该算法改编自SICP的exercise 1.19:
public static BigInteger fibonacci(int n) {
int count = n;
BigInteger tmpA, tmpP;
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ZERO;
BigInteger p = BigInteger.ZERO;
BigInteger q = BigInteger.ONE;
BigInteger two = new BigInteger("2");
while (count != 0) {
if ((count & 1) == 0) {
tmpP = p.multiply(p).add(q.multiply(q));
q = two.multiply(p.multiply(q)).add(q.multiply(q));
p = tmpP;
count >>= 1;
}
else {
tmpA = b.multiply(q).add(a.multiply(q).add(a.multiply(p)));
b = b.multiply(p).add(a.multiply(q));
a = tmpA;
count--;
}
}
return b;
}
在本书的链接章节中,有一个关于它是如何工作的解释(向下滚动到练习1.19),并且声明:
这是一个聪明的算法,以对数步数计算斐波纳契数...这个练习是由Joe Stoy根据安德尔Kaldewaij的一个例子提出的。 1990. 编程:算法的推导。
当然,如果需要反复计算相同的值,可以通过已计算的memoizing结果来实现进一步的性能提升,例如使用地图存储以前的值。
答案 1 :(得分:4)
您的实现不适用于任何正确的数字,因为它会使堆栈溢出。
我认为没有理由在这里使用递归。递归很漂亮,但通常更重(它依赖于语言)。这是一个简单的for
循环的工作实现:
private static BigInteger[] fibTmp = {BigInteger.ZERO, BigInteger.ONE};
private static int maxCached = 1;
public static BigInteger fibonacci(int v) {
if (fibTmp.length<=v) {
fibTmp = Arrays.copyOf(fibTmp, v*5/4);
}
for (; maxCached<v;) {
maxCached++;
BigInteger v1 = fibTmp[maxCached - 1];
BigInteger v2 = fibTmp[maxCached - 2];
fibTmp[maxCached] = v1.add(v2);
}
return fibTmp[v];
}
这是直接实现,而没有在文献中寻找有效的斐波那契算法。你最好找他们。
另请注意,基于缓存的实现内存成本很高,只有多次调用该函数才有意义。
答案 2 :(得分:0)
首先,您正在使用递归,这在时间和空间复杂性方面都不高效。你应该使用迭代方法。
然后,如果额外的内存或空间不是交易破坏者,并且性能非常重要,您可能需要预先计算以后要计算的所有数字,并将它们存储在数组或磁盘上(如果它也是如此)非常适合你的记忆。之后您可以在恒定时间内获得该值。