问题是找到第1000个素数。我为此编写了以下python代码。问题是,我得到了10号,20号素数的正确答案,但之后每增加10分,就让我失去了一个。我无法在这里发现错误:(
count=1 #to keep count of prime numbers
primes=() #tuple to hold primes
candidate=3 #variable to test for primes
while count<20:
for x in range(2,candidate):
if candidate%x==0:
candidate=candidate+2
else : pass
primes=primes+(candidate,)
candidate=candidate+2
count=count+1
print primes
print "20th prime is ", primes[-1]
如果你想知道,count初始化为1因为我没有测试2作为素数(我从3开始)而candidate
正在增加2因为只有奇数可以是素数。我知道还有其他解决这个问题的方法,比如素数定理,但我想知道这种方法有什么问题。如果您有任何优化,请建议。
谢谢
答案 0 :(得分:8)
test_generators.py中有一个很好的Sieve of Eratosthenes生成器实现:
def intsfrom(i):
while 1:
yield i
i += 1
def firstn(g, n):
return [g.next() for i in range(n)]
def exclude_multiples(n, ints):
for i in ints:
if i % n:
yield i
def sieve(ints):
prime = ints.next()
yield prime
not_divisible_by_prime = exclude_multiples(prime, ints)
for p in sieve(not_divisible_by_prime):
yield p
primes = sieve(intsfrom(2))
>>> print firstn(primes, 20)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
答案 1 :(得分:5)
有许多(!)需要使用Python代码进行改进,但要回答您的具体问题:
当你找到一个除数(candidate % x == 0
)时,你增加了候选者,但你没有对x
做任何事情。这可能会导致两个问题:
candidate
可能有一个除数,但它比任何被测试的x
小 - 因为在循环的下一次迭代中测试的开始时x
比值高一个x
之前有过;不在2
。candidate
可能有一个除数,但它比<{1}} 更大,因为你从x
的值中取x
启动循环时的值2
。答案 2 :(得分:3)
我不认为这是测试您认为它正在测试的内容。看起来你正试图说“对于2和我的候选人之间的每个数字,检查候选人是否可以被该数字整除”。但是,当你找到一个素数(候选%x == 0)时,你只是递增候选者 - 你仍然需要重新开始你的“for x in ...”循环,因为候选人已经改变了。 / p>
这就是我从代码中看到的内容;当然还有很多其他方法和其他优化方法可以在这里使用。
答案 3 :(得分:2)
很高兴知道每个大于3的素数都可以写成: 6K-1 / + 1。
当你正在寻找下一个候选人时,你总是可以写这样的东西(代码片段在C中):
a=1;
...
candidate=6*k+(a=(a==-1)?1:-1);
if(a==1){
k++;
}
我不久前用过的函数来确定第n个素数,其中LIM是你要找的第n个数字(C代码):
int sol2(){
int res,cnt,i,k,a;
res=-1;
i=1;
cnt=3;
k=1;
a=1;
while (1){
if (util_isprime(cnt)){
i++;
if (i==LIM){
res=cnt;
break;
}
}
/* 6k+/-1 starting from 6*1-1 */
cnt=6*k+(a=(a==-1)?1:-1);
if(a==1){
k++;
}
}
return res;
}
答案 4 :(得分:2)
声明中:
for x in range(2,candidate)
您可以通过扫描到sqrt(候选)来减少迭代次数
如果候选人可以被x整除,那么我们 可以为某些b写出candidate = x * b。如果是x 小于或等于b,然后是x 必须小于或等于 候选人的平方根
答案 5 :(得分:0)
至于优化,如果您确定要遵循此实现,则可以避免查看以下数字:
不要忘记添加5和11作为素数!
答案 6 :(得分:0)
除非我非常错误,否则无论是否找到除数,您总是将当前候选人添加到素数列表中。你附加到素数列表的代码(将前面提到的不可变元组注释放在一边)超出了整数除数的测试范围,因此总是运行。
答案 7 :(得分:0)
如果您想要任何远程效率的东西,请执行Sieve of Eratosthenes - 它就像现在一样简单。
MAX = 10000
candidates = [True] * MAX
candidates[0] = False
candidates[1] = False
primelist = []
for p,isprime in enumerate(candidates):
if isprime:
primelist.append(p)
for n in range(2*p,MAX,p):
candidates[n] = False
print primelist[1001]
答案 8 :(得分:0)
FYI ...我用以下代码解决了它,虽然它可以进行更多优化,我只想先以这种方式解决它。谢谢大家的帮助。
from math import *
primes=[2,3]
count=2
testnumber=5
while count<1000:
flag=0
for x in range(2,testnumber):
if x<=sqrt(testnumber):
if testnumber%x==0:
#print testnumber , "is not a prime"
flag=1
else : pass
if flag!=1:
#print testnumber , "is a prime"
primes=primes+[testnumber]
count=count+1
testnumber=testnumber+2
#print primes
print "1000th prime is ", primes[-1]
我现在将看看你们提到的所有其他算法
答案 9 :(得分:0)
c初学者
#include<stdio.h>
int main ()
{
int a,s,c,v,f,p,z;
while(scanf("%d",&f) !=EOF){
p=0;
for(z=1;p<f;z++){
s=2;
a=z;
while(s<a){
if(a%s==0)s=a+1;
else s=s+1;
}
if (s!=a+1)p++;
}
printf("%d\n",a);
}
return 0;
}