在python中打印一系列素数

Posted

技术标签:

【中文标题】在python中打印一系列素数【英文标题】:Print series of prime numbers in python 【发布时间】:2012-07-22 03:01:52 【问题描述】:

我在打印一系列从 1 到 10 的素数时遇到问题。我无法弄清楚我的代码有什么问题。

这是我写的;它打印所有奇数而不是素数:

for num in range(1, 101):
    for i in range(2, num):
        if num % i == 0:
            break
        else:
            print(num)
            break

【问题讨论】:

Fastest way to list all primes below N的可能重复 is_prime = lambda n: all( n%i != 0 for i in range(2, int(n**.5)+1) ) 【参考方案1】:
def prime_number(a):
    yes=[]
    for i in range (2,100):
        if (i==2 or i==3 or i==5 or i==7) or (i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%(i**(float(0.5)))!=0):
            yes=yes+[i]
    print (yes)

【讨论】:

yes=[2,3,5,7]; for i in range (8,100): if (i%2!=0 and ... and i%7!=0): yes+=[i].【参考方案2】:

这是一个简单直观的检查它是否是 RECURSIVE 函数中的素数的版本! :)(我是作为麻省理工学院的家庭作业完成的) 在 python 中它运行得非常快,直到 1900。如果你尝试超过 1900,你会得到一个有趣的错误 :) (你想检查你的计算机可以管理多少个数字吗?)

def is_prime(n, div=2):

    if div> n/2.0: return True

    if n% div == 0:
        return False
    else:
        div+=1
        return is_prime(n,div)

#The program:
until = 1000
for i in range(until):
    if is_prime(i):
        print i

当然……如果你喜欢递归函数,这个小代码可以用字典来升级,以大大提高它的性能,并避免那个有趣的错误。 这是一个带有 MEMORY 集成的简单 1 级升级:

import datetime
def is_prime(n, div=2):
    global primelist
    if div> n/2.0: return True
    if div < primelist[0]:
        div = primelist[0]
        for x in primelist:
            if x ==0 or x==1: continue
            if n % x == 0:
                return False
    if n% div == 0:
        return False
    else:
        div+=1
        return is_prime(n,div)


now = datetime.datetime.now()
print 'time and date:',now
until = 100000
primelist=[]
for i in range(until):
    if is_prime(i):
        primelist.insert(0,i)
print "There are", len(primelist),"prime numbers, until", until
print primelist[0:100], "..."

finish = datetime.datetime.now()
print "It took your computer", finish - now , " to calculate it"

这是结果,我打印了找到的最后 100 个素数。

时间和日期:2013-10-15 13:32:11.674448

有 9594 个素数,直到 100000

[99991,99989,99971,99961,99929,99923,99907,99901,9981,99877,99871,99859,99839,99859,99839,99833,99839,99823,99817,99823,99817,99809,99793,99787,99793,99787,99767,99787,99767,99787,99767,99787,99767,99787,99767,99761,99767,99761,99767,99761,99733, 99721,99719,99713,99779,99707,99689,99679,99667,99661,99643,99661,9961,99623,99619,99607,99581,99577,99581,99577,99581,99563,9959,99563,99559,99563,99559,99563,99559,99563,99559,99551,99529,99527,99529,99527,99523,99527,99523,99497,99523,99497,99487,99469, 99439,99431,99397,99391,99397,99391,99377,99371,99367,99349,99347,99349,99289,99277,99289,99277,99259,99257,99259,99257,99251,99241,99233,99223,99191,992223,99191,99181,99173,99149,9911,99149,99139, 99137,99133,99131,99119,99109,99103,99089,99083,99089,99083,99079,99053,99041,99023,99017,9903,99017,9993,98999,98993,98981,98993,98981,98963,98953,98947,98939,98947,98939,98929,98939,98929,98939,98929,98927,98929,98927,98911,98927,98911,98927,98911,98927,98911,98909, 98899, 98897] ...

你的电脑用了 0:00:40.871083 来计算它

所以我的 i7 笔记本电脑花了 40 秒来计算它。 :)

【讨论】:

there are 9592 primes below 100000 我的旧笔记本电脑花了 0.01 秒来计算它。不仔细研究,也许你的算法不是最优的。 @WillNess 当然不是!如果您想要更有效的算法检查:来自en.wikibooks.org/wiki/… 的PG7.8 我的算法很有趣,因为任何人都可以得到它为什么它有效! :) 我看过那个页面,它是……不好。它的算法效率不高。它确实重新发明了***优化,但将它与试验划分一起使用,而不是使用快得多、快得多的 Eratosthenes 筛子。 - 关于您的第一个代码:稍加修正后,它在 Ideone 上运行时间为 1.3 秒(比您的 i7 慢约 3 倍 - 所以,加速了 100 倍!),并转换为循环而不是递归 - 0.77 秒。您只需要覆盖代码中的三个字符。 :) 虽然递归函数很有趣... :) 我会考虑如何稍微改进一下 我再给你一个提示:三个字符都在一起,一个接一个。只需在它们上面输入新内容,用三个新字符替换它们。【参考方案3】:

Igor Chubin的回答可以改进。在测试 X 是否为素数时,算法不必检查直到 X 的平方根的每个数字,它只需要检查直到 sqrt(X) 的素数。因此,如果它在创建质数列表时引用质数列表,则效率会更高。下面的函数输出 b 下所有素数的列表,作为列表很方便,原因有几个(例如,当您想知道素数

from math import sqrt
def lp(b)
    primes = [2]
    for c in range(3,b):
        e = round(sqrt(c)) + 1
        for d in primes:
            if d <= e and c%d == 0:
                break
        else:
            primes.extend([c])
    return primes

【讨论】:

这是低效的:对于素数的候选人,这将访问所有先前的素数(并测试它们是否有d &lt;= e)。在达到 sqrt 之后,应该从 always 中断循环。 或完全删除 sqrt,因为它是一项昂贵的操作并比较正方形,即for d in primes: if d*d &gt; c: ...【参考方案4】:

使用python打印n个素数:

num = input('get the value:')
for i in range(2,num+1):
    count = 0
    for j in range(2,i):
        if i%j != 0:
            count += 1
    if count == i-2:
        print i,

【讨论】:

【参考方案5】:

2000 多年前希腊数学家埃拉托色尼发明的一种更好的方法不是试除法,而是通过反复抛出多个素数来进行筛分。

首先列出从 2 到最大所需素数 n 的所有数字。然后反复取最小的未交叉数并将其所有倍数划掉;未交叉的数字是素数。

例如,考虑小于 30 的数字。最初,2 被识别为质数,然后 4、6、8、10、12、14、16、18、20、22、24、26、28 和 30划掉了。接下来的 3 被确定为素数,然后 6、9、12、15、18、21、24、27 和 30 被划掉。下一个素数是 5,因此 10、15、20、25 和 30 被划掉。等等。剩下的数是素数:2、3、5、7、11、13、17、19、23 和 29。

def primes(n):
  sieve = [True] * (n+1)
  for p in range(2, n+1):
    if (sieve[p]):
      print p
      for i in range(p, n+1, p):
        sieve[i] = False

筛子的优化版本分别处理 2 并且仅筛分奇数。此外,由于所有小于当前素数平方的复合都被较小的素数划掉,所以内循环可以从 p^2 开始,而不是从 p 开始,外循环可以在 n 的平方根处停止。我会把optimized version留给你处理。

【讨论】:

筛子的性能很差,我怀疑它会比尝试除法更快,特别是如果你只尝试直到平方根。 @hochl 你错了;反例请参见 primesieve.org。 哇,不知道——但它非常复杂并且使用了多个内核...... O.o 但很有趣——谢谢! :) @hochl:不必很复杂。使用我上面讨论过的优化版本的筛子,将素数计算到一百万需要三分之一秒。使用相应的试用部门需要花费二十多倍的时间。代码ideone.com/5U2Wns。 primesieve.org 的代码更复杂,但速度更快。 不错!内存需求很大,但如果您开始计算素数,这可能不是问题。我下面的主要生成器比简单的试用部门表现得更好,但仍然是大约。慢 6 倍(2.000.000 倍:筛 0.5,简单迭代 13.2,生成器 3.76)。

以上是关于在python中打印一系列素数的主要内容,如果未能解决你的问题,请参考以下文章

Python 打印素数

素数打印机停止在 251,为啥? [复制]

在打印给定范围的最后一个素数后从函数中跳出循环

Java打印素数(质数)

Python 集合理解

Python基础训练 建议学弟学妹们收藏