[英]Find out 20th, 30th, nth prime number. (I'm getting 20th but not 30th?) [Python]
問題是找到第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]
如果您想知道,計數初始化為1,因為我沒有測試2作為素數(我從3開始)並且candidate
者正在增加2,因為只有奇數可以是素數。 我知道還有其他解決這個問題的方法,比如素數定理,但我想知道這種方法有什么問題。 如果您有任何優化,請建議。
謝謝
在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]
你的Python代碼有很多(!)需要改進,但要回答你的具體問題:
當你找到一個除數( candidate % x == 0
)時,你增加候選,但你沒有做任何關於x
事情。 這可能會導致兩個問題:
candidate
可能有一個約數,但它比任何小x
是被測試的-因為在循環的下一次迭代測試開頭x
是一個高於該值, x
收到了; 不是2
。 candidate
可能有一個約數,但它是大於 x
以往任何時候都得到,因為你把x
的值從2
到值candidate
已經當你開始循環 。 我不認為這是測試你認為它正在測試的東西。 看起來你正試圖說“對於2和我的候選人之間的每個數字,檢查候選人是否可以被該數字整除”。 但是,當你找到一個素數(候選%x == 0)時,你只是遞增候選者 - 你仍然需要重新開始你的“for x in ...”循環,因為候選人已經改變了。
這就是我從代碼中看到的內容; 當然還有很多其他方法和其他優化可供使用。
很高興知道每個大於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;
}
在聲明中:
for x in range(2,candidate)
您可以通過掃描到sqrt(候選)來減少迭代次數
如果候選者可以被x整除,那么我們可以為某些b寫出candidate = x * b。 如果x小於或等於b,則x必須小於或等於候選的平方根
至於優化,如果您確定要遵循此實現,則可以避免查看以下數字:
不要忘記添加5和11作為素數!
除非我非常錯誤,否則無論是否找到除數,你總是將當前候選者添加到素數列表中。 你附加到素數列表的代碼(拋開前面提到的不可變元組注釋)超出了整數除數的測試范圍,因此總是運行。
如果你想要任何遠程高效的東西,那就去做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]
僅供參考...我用以下代碼解決了它,雖然它可以進行更多優化,我只想先以這種方式解決它。 謝謝大家的幫助。
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]
我現在將看看大家提到的所有其他算法
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.