【问题标题】:Project Euler #7 Python欧拉计划 #7 Python
【发布时间】:2014-08-28 18:11:38
【问题描述】:

我的代码有问题。问题是:

“通过列出前六个素数:2、3、5、7、11和13,我们可以看出第6个素数是13。第10001个素数是多少?”

这就是它的样子:

div = 10001
i = 2
count = 0
prime = 0
now = []

while count < div:

    for x in range (2,i+1):
        if len(now) ==2:
            break
        elif i%x == 0:
            now.append(x)

    if len(now)==1:
        prime = i
        count += 1
    now = []
    i+=1       



print(prime)

我尝试了 div 到 1000 并且它似乎工作正常(对于 div 1000 我收到 7919)。但是,当我尝试 div = 10001 时,我什么也得不到,甚至没有错误。如果有人能帮助我,我将不胜感激。 谢谢你。

【问题讨论】:

  • 它可能运行正常,只是速度很慢。提示:有更有效的方法来计算素数。
  • 你等了多久?此代码将需要 很长 时间才能完成执行。
  • @Kevin 是的,它正在运行,我刚刚检查过它是否有效。有什么办法让它更快?
  • Sieve of Eratosthenes 对于接下来 50 多个涉及素数的欧拉计划问题应该足够快。 (对于任何说“告诉他这会破坏学习经验”的人:发现晦涩的数学理论的存在与学习如何编码无关。)
  • 筛子是一种方法,同样值得注意的是,要检查一个数字是否为素数,您还只需检查它是否可以被数字整除

标签: python primes


【解决方案1】:
# 7 10001st prime

import itertools


def is_prime(n):
    for i in range(2, n//2 + 1):
        if n % i == 0:
            return False
        else:
            continue
    return True


p = 0
for x in itertools.count(1):
    if is_prime(x):
        if p == 10001:
            print(x)
            break
        p += 1

【讨论】:

    【解决方案2】:

    试试这个代码:

    prime_list = lambda x:[i for i in xrange(2, x+1) if all([i%x for x in xrange(2, int(i**0.5+1))])][10000]
    print prime_list(120000)
    

    Python 中的 Lambda 定义了一个匿名函数,而 xrange 类似于 range,定义了一个整数范围。该代码使用列表推导并遍历数字两次直到最终数字的平方根(因此 i**0.5)。如果每个数字是范围计数中数字的倍数,则每个数字都会被消除。你留下了一个按顺序排列的素数列表。因此,您只需打印出具有正确索引的数字。

    【讨论】:

    • ... 为什么会这样?它有什么作用?它与 OP 发布的代码有什么关系?
    • 它为您提供了 euler_7 问题的解决方案,即第 10001 个素数(因为 python 编号是从 0 开始的)。
    • 是的,确实如此。但是为什么? xrange 是什么意思?还是拉姆达?这一切如何结合在一起给出答案?也就是说,它甚至没有解决或解决 OP 在询问代码时遇到的问题。它是完全不同的东西,它无助于 OP 学习任何东西,也无助于下一个人。
    • Python 中的 lambda 定义了一个匿名函数,而 xrange 与 range 类似,定义了一个整数范围。该代码使用列表推导并遍历数字两次直到最终数字的平方根(因此 i**0.5)。如果每个数字是范围计数中数字的倍数,则每个数字都会被消除。你留下了一个按顺序排列的素数列表。因此,您只需打印出具有正确索引的数字即可。
    • 你能把它放在答案中吗?
    【解决方案3】:

    只需对您的代码进行一些简单的修改(和简化),您就可以在 1/3 秒内计算出您要查找的数字。首先,我们只按照@Hashman 的建议检查平方根。接下来,我们只测试并除以奇数,将 2 作为一个特殊情况预先处理。最后,我们折腾了整个now数组长度逻辑,简单利用Python的break逻辑:

    limit = 10001
    i = 3
    count = 1
    prime = 2
    
    while count < limit:
    
        for x in range(3, int(i ** 0.5) + 1, 2):
            if i % x == 0:
                break
        else:  # no break
            prime = i
            count += 1
    
        i += 2
    
    print(prime)
    

    和以前一样,对于 1000 的限制,这给我们 7919,对于 10001 的限制,它给我们 104743。但这仍然不如 筛子快。

    【讨论】:

      【解决方案4】:
      m=0
      
      n=None
      
      s=1
      
      while s<=10001:
      
              for i in range(1,m):
      
                  if m%i==0:n=i
      
              if n==1:print(m,'is prime',s);s+=1
      
              m+=1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多