使用Python查找第n个素数

时间:2010-10-07 21:14:48

标签: python primes

当我运行这段代码时,即使只计算到第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 

4 个答案:

答案 0 :(得分:3)

查看MIT为您的作业提供的提示。我在下面引用它们:

  1. 初始化一些状态变量

  2. 生成所有(奇数)整数&gt; 1作为候选人

  3. 对于每个候选整数,测试它是否为素数

    3.1。一种简单的方法是测试是否有任何其他整数&gt; 1将候选者均分为0余数。为此,您可以使用模运算,例如,表达式a%b在将整数a除以整数b后返回余数。

    3.2。你可能会想到你需要检查哪些整数作为除数 - 当然你不需要超出你正在检查的候选人,但是你能多早停止检查

  4. 如果候选人是素数,打印出一些信息,以便知道你在计算中的位置,并更新状态变量

  5. 达到适当的最终条件时停止。在制定此条件时,不要忘记您的程序未生成第一个素数(2)

  6. 看起来像这样:

    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]]
    

答案 1 :(得分:1)

首先,根据您的主要检查算法的模糊描述,您似乎正在检查每个数字,直到您正在测试素数的数字。但实际上,您只需要测试该数字的平方根。进一步的优化是删除除了两个之外的所有偶数(你可以通过从一个增加两个并分别测试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函数的数字。

当然还有其他更有效的方法,我个人更喜欢Sieve of Atkin。但是由你来实现,我的算法将满足你的目的。

编辑:我注意到你的评论“没有任何东西正在返回/发生”,这可能是由于你的算法效率低下,如果你等了足够长的时间你会得到答案。但是,我注意到你提供的代码中没有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

答案 2 :(得分:0)

这是我为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.");}

答案 3 :(得分:-1)

下面的代码生成一个高达100万的素数列表。 使用该列表,您可以测试素数&lt; 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'