在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 <= e
)。在达到 sqrt 之后,应该从 always 中断循环。
或完全删除 sqrt,因为它是一项昂贵的操作并比较正方形,即for d in primes: if d*d > 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中打印一系列素数的主要内容,如果未能解决你的问题,请参考以下文章