簡體   English   中英

使用Python查找第n個素數

[英]Finding the nth prime number using Python

當我運行這段代碼時,即使只計算到第10個素數(而不是1000),我得到一個偏斜/頂部輸出 - 我的is_composite變量的所有“非素數”標題,我的test_num給出了素數和復合數,我的prime_count已關閉

開發人員共享的一些答案使用函數和數學導入 - 這是我們尚未涉及的內容。 我不是想要得到最有效的答案; 我只是想編寫可行的python代碼來理解循環的基礎知識。


  # test a prime by diving number by previous sequence of number(s) (% == 0).  Do this by
  # counting up from 1 all the way to 1000.

test_num = 2 #these are the numbers that are being tested for primality
is_composite = 'not prime' # will be counted by prime_count
prime_count = 0 #count the number of primes


while (prime_count<10): #counts number primes and make sures that loop stops after the 1000th prime (here: I am just running it to the tenth for quick testing)


 test_num = test_num + 1   # starts with two, tested for primality and counted if so
 x = test_num - 1  #denominator for prime equation

 while (x>2):   
  if test_num%(x) == 0:
   is_composite = 'not prime'
  else: 
   prime_count = prime_count + 1 
  x = x - 1 


  print is_composite
  print test_num
  print prime_count 

請參閱麻省理工學院為您的作業提供的提示。 我在下面引用它們:

  1. 初始化一些狀態變量

  2. 生成所有( 奇數 )整數> 1作為候選者作為素數

  3. 對於每個候選整數,測試它是否為素數

    3.1。 一種簡單的方法是測試是否任何其他整數> 1均勻地將候選者除以0余數。 為此,您可以使用模運算 ,例如,表達式a%b在將整數a除以整數b之后返回余數。

    3.2。 你可能會想到你需要檢查哪些整數作為除數 - 當然你不需要超越你正在檢查的候選人,但你能早點停止檢查多少?

  4. 如果候選者是素數,則打印出一些信息,以便您知道計算中的位置,並更新狀態變量

  5. 達到適當的最終條件時停止。 在制定這個條件時, 不要忘記你的程序沒有生成第一個素數(2)

它可能看起來像這樣:

def primes(n):
    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
    return [2] + [i for i in xrange(3,n,2) if sieve[i]]

首先,從您的主要檢查算法的模糊描述中,您似乎正在檢查每個數字,直到您正在測試素數的數字。 但實際上,您只需要測試該數字的平方根。 進一步的優化是刪除除了兩個之外的所有偶數(你可以通過從一個增加兩個並分別測試2來實現),最終得到:

def isprime(test):
    if test == 2: return True
    if test < 2 or test % 2 == 0: return False
    return not any(test % i == 0 for i in range(3, int(sqrt(test)) + 1, 2))

然后,你所要做的就是從2向上遍歷數字,檢查它們是否為素數,如果它們是,則向你的計數器添加一個。 當你達到1000停止並輸出傳​​遞給isprime函數的數字。

當然還有其他更有效的方法,我個人更喜歡AtveSieve 但是由你來實現,我的算法將滿足你的目的。

編輯:我注意到你的評論“沒有任何東西正在返回/發生”,這可能是由於你的算法效率低下,如果你等了足夠長的時間,你會得到一個答案。 但是,我注意到你提供的代碼中沒有print語句,我希望你運行的代碼有一個。

from math import sqrt

def isprime(test):
    if test == 2: return True
    if test < 2 or test % 2 == 0: return False
    return not any(test % i == 0 for i in range(3, int(sqrt(test)) + 1, 2))

test_num = 2
prime_count = 1

while (prime_count< 1000): 

 test_num = test_num + 1  

 if (isprime(test_num)):
     prime_count += 1

print test_num

這是我為C ++編寫的代碼。 但心態必須相同。

// This code was written by Mert Ener
#include <time.h>
#include <vector>
#include <iostream>

private: System::Void button1_Click_1(System::Object^  sender, 
                                          System::EventArgs^  e) { 
    using namespace std;
    UInt64 cloc = clock();
    long m = 1;
    long k = long::Parse(textBox1->Text)-2;   // The text you entered 
    std::vector<long> p(1,2);                 //   for the nth prime
    for( long n = 0; n <= k; n++ ) {
        m += 2;
        for( long l = 1; l <= n; l++ ) {
            if (m % p[l] == 0) {
                m += 2;
                l=0;}}
        p.push_back(m);}
    textBox2->Text = p[k+1].ToString(); // The textbox for the result.
    MessageBox::Show("It took me " + (clock() - cloc).ToString() 
                     + " milliseconds to find your prime.");}

下面的代碼生成一個高達100萬的素數列表。 使用該列表,您可以以合理快速的方式測試質量<1萬億。 這對於10-12位數的素數來說非常快。

import math
from itertools import islice
# number of primes below the square root of x
# works well when x is large (x > 20 and much larger)
numchecks = lambda x: int((math.sqrt(x))/(math.log(math.sqrt(x)) - 1.084)) + 1

primes = [2,3,5]
primes = primes + [x for x in range(7, 48, 2) if all((x%y for y in islice( primes, 1, int(math.sqrt(x)) )))]
primes = primes + [x for x in range(49, 2400, 2) if all((x%y for y in islice( primes, 1, numchecks(x) )))]
primes = primes + [x for x in range(2401, 1000000, 2) if all((x%y for y in islice( primes, 1, numchecks(x) )))]

您可以通過擴展上述過程來增加已保存素數的數量,但程序將花費很長時間(但僅限一次過程)。

在您的代碼中,您可以使用以下內容測試'test_num'是否為素數...

test_num = 23527631
if test_num<100:
    checks = int(math.sqrt(test_num))
else:
    checks = numchecks(test_num)

isPrime = all(test_num%x for x in islice(primes, 0, checks))
print 'The number is', 'prime' if isPrime else 'not prime'
print 'Tested in', checks, 'divisions'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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