Python中的素数生成器:数字的积累

0 投票
2 回答
4309 浏览
提问于 2025-04-17 18:34

我的生成器运行得很好:我测试过很多次。只是有个问题:随着数字的增大,程序变得越来越慢。虽然我想到了一个解决办法,但由于我刚开始学习Python不久,所以不知道该怎么做。

我的生成器长这样:

    while 0==0:
        i=input('Enter the number for which all previous shall be tested for primality: ')
        n=0
        a=[0,1,2]
        while n<=i:
            n=n+1
            for b in range(2,n):
                if n%b==0:
                    break
                if b==(n-1):
                    a.append(n)
                    print a`

我发现如果把a=[0,1,2]放到while 0==0之前,它会在程序运行时累积之前使用过的所有数字。我想改变的是,当a累积质数时,它可以用这些质数来追赶下一个未知的数字。比如说,我想要所有小于100的质数。然后,我又想要所有小于200的质数。这样的话,我就不想重新计算小于100的质数,而是希望程序跳过这些,直接从100之后的第一个质数开始。

任何建议都非常感谢,我使用的是Python 2.7。

a = [2,3,5,7,11]
while 1:
    b = input('Enter the number for which all previous shall be tested for primality: ')
    c = len(a)
    d = 0
    isprime = True
    while b<=a[c-1] and not d==c:
            if b==a[d]:
            print a[0:d]
        if d==(c-1) and not b==a[d]:
            break
        d = d + 1
    while b>a[c-1]:
        d = 0
        print a[c-1]
        if b%a[d]==0:
            isprime = False
            break
        while a[d]==a[c-1]:
            f = a[c-1] + 2
            for g in range(f,b,2):
                if b%g==0:
                    isprime = False
                    break
            if isprime:
                a.append(b)
                print a

好的,我让这个程序工作得更好,让它在找到质数时把它们存起来,以便下次找质数时使用。假设我想找小于1000的质数。程序会计算出这些质数。然后,我想知道小于2000的质数。因为程序已经找到了小于1000的质数,所以不需要重新计算。它会把所有小于或等于输入的最大数字的质数拿出来,然后用已知的质数去除新数字,找出剩下的质数。接着,它会把新的质数加到a中,继续进行。

不过,有个问题。它并没有按照我计划的方式工作,我正在努力修复这个问题。也许你们可以帮忙看看哪里出了错?

好的,我已经编辑了代码,让它运行得更快:

While 1:
    i=input('Enter the number for which all previous shall be tested for primality: ')
    n=0
    while n<=i:
        n=n+1
        a=int(n**.5)
        for b in range(2,n):
            if n%b==0:
                break
             if b==a:
                print n
                break

到目前为止,这个程序的运行时间比我原来的程序和我尝试过的其他程序都要短。在我进行的一次测试中,我让它和我第一个算法一起找出所有小于100000的质数。我的第一个算法花了大约4分钟,而我的新程序只用了大约1分40秒。可以说是一次很大的升级。

2 个回答

1

有很多种找素数的方法,其中“筛法”是最快的。如果你知道怎么用 C语言扩展Python,你可以使用 primesieve 这个工具。下面是一个用Python实现的 埃拉托斯特尼筛法 的例子,如果你还有其他问题,随时告诉我:

from __future__ import generators
def eratosthenes():
    '''Yields the sequence of prime numbers via the Sieve of Eratosthenes.'''
    D = {}  # map composite integers to primes witnessing their compositeness
    q = 2   # first integer to test for primality
    while 1:
        if q not in D:
            yield q        # not marked composite, must be prime
            D[q*q] = [q]   # first multiple of q not already marked
        else:
            for p in D[q]: # move each witness to its next multiple
                D.setdefault(p+q,[]).append(p)
            del D[q]       # no longer need D[q], free memory
        q += 1
-1

这个方法应该会更快:

while 1:
    i=input('Enter the number for which all previous shall be tested for primality: ')
    n=5
    a=[2,3]
    while n<=i:
        n=n+1
        isPrime = True
        for b in a:
            if n%b==0:
                isPrime = False
                break
        if isPrime:
            a.append(n)
            print a

不过我觉得除了使用更高级的算法和处理非常大的数字(比如10的100次方),你可能很难让速度比O(看看sebastian的评论)更快。

随着数字变大,速度总是会变慢。

撰写回答