Prime Generator(用于Spoj解决方案)

时间:2017-09-03 09:25:39

标签: python algorithm sieve-of-eratosthenes

我有几天在使用这个Prime Generator算法来解决SPOJ问题。问题是从数字m,n打印至少100000个素数,在6秒内n <= 1000000000。我有这个实现,在11.701067686080933秒打印100000素数。是否有可能超越Python中的时间限制(6s)。 我觉得我在分段筛功能中遗漏了一些东西,因为我刚刚实现了它如何理解算法的工作原理,也许改变可以使它变得更好。

这里有一些帮助。

def sieveOfErosthen(m):
    limit=m+1
    prime=[True]*limit

    for i in range(2,int(m**0.5)):
        if prime[i]:
            for x in range(i*i,limit,i):
                prime[x]=False
    return prime  

def segmentedSieve(m,n):
    limit= n+1
    segment=[True]*limit

    for j in range(2,int(n**0.5) ):
        if sieveOfErosthen(j):
            for b in range(j*(m//j),limit,j):
                if b >j:
                    segment[b]=False
    for v in range(m,limit):
        if segment[v]:
            print(v)
    return True

2 个答案:

答案 0 :(得分:0)

此代码是一场灾难。让我们从最明显的错误开始:

if sieveOfErosthen(j):

(这特别令人困惑,因为您的原始代码没有定义此功能,而是定义了EratosthenesSieve() - 您的帖子的后期编辑器将其映射到另一个我认为是正确的。)什么{ {1}}回来了?它返回一个数组,因此在sieveOfErosthen(j)的布尔上下文中,此测试始终为if,因为如果True为正数,则数组始终包含至少一个元素!

将其更改为j,并确保您的输出不会更改。剩下的是一个非常低效的筛选算法,我们可以通过各种方式加速:

if True:

这段代码可以很容易地在几分之一秒内找到前100,000个素数,但最终,如果def segmentedSieve(m, n): primes = [] limit = n + 1 segment = [True] * limit if limit > 0: segment[0] = False if limit > 1: segment[1] = False for j in range(2, int(limit**0.5) + 1): if segment[j]: for b in range(j * j, limit, j): segment[b] = False for v in range(m, limit): if segment[v]: primes.append(v) return primes (十亿)那么我们必须假设最坏的情况,即6秒内的最后100,000个素数n <= 1000000000中的一些合适的m,它将使这段代码分钟而不是秒。

最后,您没有实施分段筛 - 您实施了常规筛,只是略过了要求的范围。我建议您阅读segmented sieves in Wikipedia或其他地方,如果您需要分段筛,请重新开始。

答案 1 :(得分:0)