在Fibonacci序列中找到第n个素数(更快)

时间:2015-04-13 17:55:48

标签: python primes fibonacci

我正在修读我的第一个编程课程,我的任务是列出Fibonacci序列中第n个素数。 到目前为止,我已经想出了这个:

 num = int(input("Enter a number: "))

a = 1
b = 1
c = 0
count = 0
isPrime = True 

while (count < num):
    isPrime = True
    c = a + b

    for i in range(2,c):
        if (c % i == 0):
            isPrime = False
            break

    if (isPrime):
        print (c)
        count = count + 1
    a = b
    b = c

这样可行,但对于大于10的任何输入需要很长时间,有人可以帮我弄清楚如何让它更快一点吗?我认为这是因为a,b和c最终变得非常大,但我不确定如何解决这个问题。

4 个答案:

答案 0 :(得分:1)

fib = lambda n:reduce(lambda x,n:[x[1],x[0]+x[1]], range(n),[0,1])[0]

最短和最快的斐波纳契在python中为一个线性脚本编号。

>>> fib(1000)
43466557686937456435688527675040625802564660517371780402481729089536555417949051
89040387984007925516929592259308032263477520968962323987332247116164299644090653
3187938298969649928516003704476137795166849228875L

找到here

答案 1 :(得分:1)

将斐波纳契数的生成与素性测试分开是最容易的。这是Miller-Rabin素性测试的Python实现:

def isPrime(n, k=5): # miller-rabin
    from random import randint
    if n < 2: return False
    for p in [2,3,5,7,11,13,17,19,23,29]:
        if n % p == 0: return n == p
    s, d = 0, n-1
    while d % 2 == 0:
        s, d = s+1, d/2
    for i in range(k):
        x = pow(randint(2, n-1), d, n)
        if x == 1 or x == n-1: continue
        for r in range(1, s):
            x = (x * x) % n
            if x == 1: return False
            if x == n-1: break
        else: return False
    return True

然后很容易生成斐波纳契数并测试它们的素数:

a, b, f = 1, 1, 2
while True:
    if isPrime(f): print f
    a, b, f = b, f, b+f

找到第22个主要的斐波那契数字不会花太长时间:

357103560641909860720907774139063454445569926582843306794041997476301071102767570483343563518510007800304195444080518562630900027386498933944619210192856768352683468831754423234217978525765921040747291316681576556861490773135214861782877716560879686368266117365351884926393775431925116896322341130075880287169244980698837941931247516010101631704349963583400361910809925847721300802741705519412306522941202429437928826033885416656967971559902743150263252229456298992263008126719589203430407385228230361628494860172129702271172926469500802342608722006420745586297267929052509059154340968348509580552307148642001438470316229

您可以在http://ideone.com/L1oQgO看到该计划的实际效果。有关详情,请参阅A005478A001605

答案 2 :(得分:1)

你绝对应该使用以下众所周知的启发式方法:

  

要检查N是否为素数,您只需将其除以   数字从2到sqrt(N)

@ user448810在Miller-Rabin素性测试中隐式使用它。但是,如果您只想改进自己的代码。

答案 3 :(得分:0)

此代码与单行代码的作用相同,且更具可读性:

def fib(n):
    a=1
    b=1
    for i in range(n-2):
        a,b = b,a+b
    return b