簡體   English   中英

找出第20,第30,第n個素數。 (我要20歲但不是30歲?)[Python]

[英]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事情。 這可能會導致兩個問題:

  1. candidate可能有一個約數,但它比任何小x是被測試的-因為在循環的下一次迭代測試開頭x是一個高於該值, x收到了; 不是2
  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必須小於或等於候選的平方根

至於優化,如果您確定要遵循此實現,則可以避免查看以下數字:

  1. 結束於5,因為它們可被5整除。
  2. 由相同的數字組成,例如22,33,44,55,66等,因為它們可被11整除。

不要忘記添加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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM