【问题标题】:Prime Generator(for Spoj solution)Prime 生成器(用于 Spoj 解决方案)
【发布时间】:2018-02-11 19:16:33
【问题描述】:

我有好几天都在为这个用于 SPOJ 问题的 Prime Generator 算法而苦苦挣扎。问题状态是在 6 秒内从数字 m,n 打印至少 100000 个素数,其中 n

这里将不胜感激。

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

【问题讨论】:

  • 请正确格式化您的代码,因为它包含多个语法错误。
  • 请看我的分段筛HERE

标签: python algorithm sieve-of-eratosthenes


【解决方案1】:

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

if sieveOfErosthen(j):

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

将此更改为 if True: 并查看您的输出没有更改。剩下的是一个非常低效的筛分算法,我们可以通过各种方式对其进行加速:

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

这段代码可以在几分之一秒内轻松找到前 100,000 个素数,但最终,如果n <= 1000000000(十亿)那么我们必须假设最坏的情况,即在 6 秒内找到最后 100,000 个素数segmentedSieve(m, 1000000000) 中的 m,这将花费此代码分钟而不是秒。

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

【讨论】:

    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多