【问题标题】:Running time of prime finding algorithm in PythonPython中素数查找算法的运行时间
【发布时间】:2019-03-06 07:09:53
【问题描述】:

问题:

我有以下任务:

[...] 编写一个程序,接收一个大于 1 的正整数,并验证它是素数还是合数。

解决办法:

我想出了以下内容:

n=int(input())
flag=True
for i in range(2,n//2+2):
    if n%i==0:
        print("Not prime.")
        flag=False
        break
if flag==True:
    print("Prime.")

这似乎是正确的。然后,我决定尝试一下,看看使用大整数输入会怎样,10^9+7 看起来是个不错的选择。但是,程序似乎根本没有运行完,一直运行了 30 多秒,直到我决定将其杀死。

但是,考虑到算法中的循环最多运行 ~5*10^8 次,并考虑到现代计算机在一秒钟内可以执行的大量计算,那运行时间不是不成比例地长吗?

这里发生了什么?

10^9+7 在 Python 中是否像在 C 中一样作为 int 类型计算的“上限”工作,从而以某种方式“溢出计算”?还是我的算法有问题?

提前致谢!

【问题讨论】:

  • 顺便说一句,如果你基于(你认为的)埃拉托色尼筛子,那么你可能学会了一种通常被误认为筛子的试除法。 Eratosthenes 的实际筛子不进行可分性测试。
  • @user3386109 range 在 Python 3 中的行为与 Python 2 中的 xrange 类似 - 在 Python 3 中不再有 xrange。 OP没有说清楚,但是看int(input(...))print(..),我猜他正在使用Python 3。
  • @Vinicius 不需要测试最多一半的除数,您可以停在它的平方根处,对于大数来说它要小得多。
  • @user2357112 你说得对,这不是筛子;我最后一次真正处理它是在高中时,所以我有点误会了。
  • 另外,很抱歉没有说清楚,@ThierryLathuille -- 我确实在使用 Python 3。我会编辑这篇文章。哇,我绝对明白为什么停在平方根上是有效的。不敢相信我没有注意到,这确实是一个很大的不同。谢谢!

标签: python algorithm runtime primes


【解决方案1】:

当然,在 Python 这样的解释型语言中,速度会慢一些——与等效的 C 实现相比,有时您可能会损失一到两个数量级的性能。但是,您的算法渐进地比必要的差得多。你的算法是O(n),但是通过只检查可除性直到n 的平方根,你可以达到O(sqrt(n)) 时间。您还可以通过实施车轮分解来通过一些恒定因素来加快速度。轮子{2, 3}{2, 3, 5} 相当普遍,但是当你向轮子添加更多素数时,你会得到递减的回报。使用{2} 轮保持简单,我们可以跳过所有偶数(除了 2),因为它们都不是素数。

def is_prime(n):
    if n < 3:
        return n == 2
    if not n % 2:
        return False

    for i in range(3, int(n ** 0.5) + 2, 2):
        if not n % i:
            return False
    return True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多