我已经很长时间没有编程了,我只是为了好玩而做这件事,而且我不太懂高级Python,但...... 我写了这篇文章,我想知道它是否真的是一个Eratosthenes Sieve程序,如果是,我怎么能让它更快。我真的不希望有人发布一个解决方案,但更多的是告诉我如何适应我的。
def eratSieve(n):
all = []
for a in range(2, n+1):
all.append(a)
for b in all:
for i in range(2,int(round(len(all)/b))):
while i*b in all:
all.remove(i*b)
i+=1
return all
感谢您的帮助。
BTW - 它在Python 2.7中
答案 0 :(得分:1)
它不能正常工作。
主要问题是您循环使用all
中的所有值,并在while
中删除all
中的某些元素。
这样就不会考虑all
中的某些值,因此该函数不会删除所有非素数
尝试在n = 100时执行它,你得到的结果是
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99
虽然它应该是
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
(来自http://en.wikipedia.org/wiki/Prime_number)
此外,第二个for
的范围是错误的,因为您考虑了列表的长度,而不是b
的当前值,因此您只检查前50个中的2的倍数值,前17个中的3的倍数,前9个中的5个,依此类推。从b = 13
开始,您永远不会进入内部for
,因为int(round(len(all)/b)) = 1
因此您有类似for i in range(2,1)
答案 1 :(得分:0)
我同意Gianluca,我有一个可能的解决方案:保持你的主阵列(all
)为bools并标记非素数,但不要删除它们。它也可能更快,因为您不会更改列表大小。
轻微的事情:如果你想把它作为整数,你可以在开头写all = range(2, n+1)
。
答案 2 :(得分:0)
您的方法会产生错误的结果。错误在于for i
循环。在这里进行调整,并进行测试:
known_primes = [
2,3,5,7,11,13,17,19,23,29,
31,37,41,43,47,53,59,61,67,71,
73,79,83,89,97,101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,
233,239,241,251,257,263,269,271,277,281,
283,293,307,311,313,317,331,337,347,349,
353,359,367,373,379,383,389,397,401,409,
419,421,431,433,439,443,449,457,461,463,
467,479,487,491,499,503,509,521,523,541,
547,557,563,569,571,577,587,593,599,601,
607,613,617,619,631,641,643,647,653,659,
661,673,677,683,691,701,709,719,727,733,
739,743,751,757,761,769,773,787,797,809,
811,821,823,827,829,839,853,857,859,863,
877,881,883,887,907,911,919,929,937,941,
947,953,967,971,977,983,991,997,1009,1013,
1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,
1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,
1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,
1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,
1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,
1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,
1453,1459,1471,1481,1483,1487,1489,1493,1499]
def eratSieve(n):
all = []
for a in range(2, n+1):
all.append(a)
for b in all:
for i in all[all.index(b):]:
while i*b in all:
all.remove(i*b)
i+=1
return all
for N in range(1500):
for n in eratSieve(N):
if n not in known_primes:
print N,n
答案 3 :(得分:-1)
def primes(N):
primes = [x for x in (2, 3, 5, 7, 11, 13) if x < N]
if N < 17: return primes
candidators = [x for x in xrange((N - 2) | 1, 15, -2)
if x % 3 and x % 5 and x % 7 and x % 11 and x % 13]
top = int(N ** 0.5)
while (top + 1) * (top + 1) <= N: top += 1
while True:
p = candidators.pop()
primes.append(p)
if p > top: break
candidators = filter(p.__rmod__, candidators)
candidators.reverse()
primes.extend(candidators)
return primes
我认为这段代码会更快...