2016-12-28 3 views
2

これは、n番目の素数を取得する関数です。私はそれが前に行われていることを知っていますし、私の方法はあまり効率的ではないかもしれません(新しいコーダーは過去に微妙に変化していました)。 とにかく、以下のコードは動作し、指定されたインデックスの素数を返します。 すなわち:Python 3:100以上のインデックスのリストは、インデックス47の後に戻って循環します。なぜですか?どうやってこれをやめるの?

ind = 4 
final[1,2,3,5,7,11] 
return final[ind-1] 
returns: 5 

しかし、最終[51-1]はいただきました!最後の[3-1]でを返します。インデックス47の後のように、ループして戻ってきます。私はファイナルに含まれるリスト全体を印刷しました。 47歳を過ぎてもすべての素数を印刷します。何が起きているのかわかりません。 Pythonのリストにはいくつかの制限がありますか?ここで

コードです:

def nthPrime(ind): #gets nth prime number. IE: 5th prime == 11. works based off very in-efficient version of Sieve of Eratosthenes. but in increments of 200 
    p = {} 
    T = 2 
    incST = 2 
    incEND = incST + 200 
    final=[1] 

    while len(final) < ind: 
     for i in range(incST,incEND): 
      p[i] = True 

     while T <= math.sqrt(incEND): 
      l = 0 
      while l <= incEND: 
       p[T**2 + (T*l)] = False 
       l+=1 
       if T**2+(T*l) > incEND: 
        break 

      for k,v in p.items(): 
       if p[k] == True and k > T: 
        T = int(k) 
        break 

     for k in p: 
      if p[k] == True: 
       final.append(k) 

     incST = incEND + 1 
     incEND = incST + 200 

    ''' 
    currently function works perfectly for 
    any index under 48. 
    at index 48 and above it seems to start 
    back at index 1. 
    IE: final[51] 
    ^would actually return final[4] 
    ''' 


    return final[ind-1] 
+0

あなたの方法が何であるか(可能な限り簡潔に)言葉で説明しようと、あなたはそれを実装しようとしたか、バグはおそらくかなり明らかにされる場合早く。 – ekhumoro

+0

www.pythontutor.comでいつでもPythonコードを視覚化して、どこが間違っているのかを理解することができます。 – Arya

答えて

1

あなたはあなたのリストにいくつの素数を数える必要がありますが、ループ内でfinalに累積するので、すべての数値をループの中に数回まで追加します。 199年以降に2で再び始まります。

また、辞書を使用して注文に頼ることは危険です。 iterating時にソートする必要があります。

私のソリューションだけに繰り返し処理を行う場合、私はまた、辞書を並べ替え、ループを終了する際に知っている、とだけ最後にリストを作成するために素数をカウント1を省略し、1

によってインデックスをシフト確認してください。これを行うには

import math 

def nthPrime(ind): #gets nth prime number. IE: 5th prime == 11. works based off very in-efficient version of Sieve of Eratosthenes. but in increments of 200 
    p = {} 
    T = 2 
    incST = 2 
    incEND = incST + 200 

    lenfinal = 1 
    while lenfinal < ind: 
     for i in range(incST,incEND): 
      p[i] = True 

     while T <= math.sqrt(incEND): 
      l = 0 
      while l <= incEND: 
       p[T**2 + (T*l)] = False 
       l+=1 
       if T**2+(T*l) > incEND: 
        break 

      for k,v in sorted(p.items()): 
       if v and k > T: 
        T = int(k) 
        break 


     incST = incEND + 1 
     incEND = incST + 200 
     # compute length, no need to order or to actually create the list 
     lenfinal = sum(1 for k,v in p.items() if v) 

    # now compose the list 
    final = [k for k,v in sorted(p.items()) if v] 

    return final[ind-2] 
+0

うわー。素晴らしい応答。 – user3331024

+0

うわー。素晴らしい応答。私はこれからずっと学んだ。私が間違っていたことだけではありません。しかし、v == Trueなら明示的に述べる必要はないことにも気づいていませんでした。 また、リストの作成中にifステートメントを実行できることもわかりません。 ありがとうございます。これはうまくいった。 – user3331024

+0

はい、http://codereview.stackexchange.comのほぼ候補者です。私は1つの要素を取るためにリスト全体を生成することが最適化されていないことは確かではありません。さて、それは動作します。不要なハッシングを避けるために、辞書を選んだのではなく、リストを選んだでしょう。 –

-1

これは、問題は、あなたが結果を計算する方法にあなたの計算であり、Pythonの問題ではありません。あなたがfinal[51]を行うと、それが実際にその位置を保持している値を返し、次の操作を行います。

# Modify your line 
# return final[ind-1] 
# return final 

# Call your method 
o_final = nthPrime(100) 
for k in range(len(o_final)): 
    print(k, y[k]) 

は、その後、あなたはposのあなたは、次のいずれかに到達し、インクリメント保つ93ことを実現します。

+0

それはそうしているようです。 'nthPrime(4)'は最初の4つの素数ではなく、4番目の素数を返すべきです。 – Barmar

1

、より効率的な方法は、再帰関数のようになります。 私はコード内のいくつかの説明を入れます。使い方の

def nthPrime(ind): 
    first_prime=1        #first prime number 
    number = 1         # all numbers that we will check, this will be incremented 
    prime_numbers = [first_prime]    # The list of prime numbers we will find 

    def findPrimeInPosition(ind, number): 
     if ind > len(prime_numbers):   # This recursive function will exit if find a sufficient number of primes 
      number+=1       # incrementing to check the next number 
      is_prime = True     # Assuming number is a prime 

      for p in prime_numbers[1:]:  # Check if it is a prime 
       if not number % p: 
        is_prime = False 

      if is_prime: 
       prime_numbers.append(number) # Add to the list of primes 

      findPrimeInPosition(ind, number) 
     return prime_numbers[-1]    # Get the last element found 
    return findPrimeInPosition(ind, number) 

例:

print nthPrime(47) 
>> 199 
print nthPrime(48) 
>> 211 
+0

これははるかにきれいに見えます。今それで遊んでいます。ありがとうございました。あなたのオリジナルとあなたの時間の比較を投稿できるかどうかを確認してください。 – user3331024

+0

だから、もっと低いインデックスでは少し速く見えます。私は高いインデックスをテストすることができませんでした。 Pythonはind = 2000でエラーを投げ始めます: RecursionError:最大再帰深度が比較で超えました これは大量の数値を処理できる必要があります。少なくとも20万のインデックスまで – user3331024

+0

だから、再帰関数をwhileループに変更しました。あなたのコードは、ほぼ半分の時間を削減します。 >>> OP.nthPrime(47) [211、0.004000425338745117] >>> OP.nthPrime2(47) [211、0.003000497817993164] >>> OP.nthPrime(2000) [17539 、11.65716552734375] >>> OP.nthPrime2(2000) [17389,6.237623691558838] >>> – user3331024

関連する問題