我正在解决Euler项目,其中遇到一个问题,问我前1000位斐波那契数字的索引。
首先,我使用了这段代码,但是花费了太多时间。
def fibonacci(num):
if (num==0):
return 0;
if(num==1):
return 1;
return fibonacci(num-1) + fibonacci(num-2);
def numOfDigits(num):
numOfDigits = 0;
while (num>0):
num = num/10;
numOfDigits += 1;
return numOfDigits;
def main():
n=0;
while(n>=0):
fib = fibonacci(n);
num = numOfDigits(fibonacci(n));
print n,"\t",fib;
if(num>=1000):
break;
n+=1;
print "answer:",n;
main();
然后我在Google上搜索了一下,发现binnet's formula使其变得非常快。
import math as mt;
def fibonacci(num):
phi = (mt.sqrt(5)+1.00)/2.00;
return ((phi**num)-((-phi)**(-num)))/mt.sqrt(5);
def numOfDigits(num):
numOfDigits = 0;
while (num>0):
num = num/10;
numOfDigits += 1;
return numOfDigits;
def main():
n=0;
while(n>=0):
fib = fibonacci(n);
num = numOfDigits(fibonacci(n));
print n,"\t",fib;
if(num>=1000):
break;
n+=1;
print "answer:",n;
main();
但是随后出现了问题:
1471 1.17851144788e+307
1472 1.9068715788e+307
1473 3.08538302668e+307
1474 4.99225460548e+307
Traceback (most recent call last):
File "src/ThousandDigitFibonacciNum.py", line 29, in <module>
main();
File "src/ThousandDigitFibonacciNum.py", line 22, in main
fib = fibonacci(n);
File "src/ThousandDigitFibonacciNum.py", line 10, in fibonacci
return ((phi**num)-((-phi)**(-num)))/mt.sqrt(5);
OverflowError: (34, 'Result too large')
第一个疑问是结果太大而无法返回或计算? 那么解决方案是什么?
答案 0 :(得分:2)
对于每个n
,您都在重新计算所有斐波那契数F(1)...F(n-1)
,以便计算F(n)
。相反,您只能计算一次每个斐波那契数,并检查每个斐波那契数是否具有合适的位数:
def fibo():
a = 0
b = 1
while True:
yield a
a, b = b, a+b
for index, number in enumerate(fibo()):
if len(str(number)) == 1000:
print(index)
break