简体   繁体   English

使用Python查找第n个素数

[英]Finding the nth prime number using Python

When I run this code, even for just counting to the 10th prime number (instead of 1000) I get a skewed/jacked output--all "not prime" titles for my is_composite variable, my test_num is giving me prime and composite numbers, and my prime_count is off 当我运行这段代码时,即使只计算到第10个素数(而不是1000),我得到一个偏斜/顶部输出 - 我的is_composite变量的所有“非素数”标题,我的test_num给出了素数和复合数,我的prime_count已关闭

Some of the answers that developers have shared use functions and the math import--that's something we haven't yet covered. 开发人员共享的一些答案使用函数和数学导入 - 这是我们尚未涉及的内容。 I am not trying to get the most efficient answer; 我不是想要得到最有效的答案; I am just trying to write workable python code to understand the basics of looping. 我只是想编写可行的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 

See the hints given by MIT for your assignment. 请参阅麻省理工学院为您的作业提供的提示。 I quote them below: 我在下面引用它们:

  1. Initialize some state variables 初始化一些状态变量

  2. Generate all ( odd ) integers > 1 as candidates to be prime 生成所有( 奇数 )整数> 1作为候选者作为素数

  3. For each candidate integer, test whether it is prime 对于每个候选整数,测试它是否为素数

    3.1. 3.1。 One easy way to do this is to test whether any other integer > 1 evenly divides the candidate with 0 remainder. 一种简单的方法是测试是否任何其他整数> 1均匀地将候选者除以0余数。 To do this, you can use modular arithmetic , for example, the expression a%b returns the remainder after dividing the integer a by the integer b. 为此,您可以使用模运算 ,例如,表达式a%b在将整数a除以整数b之后返回余数。

    3.2. 3.2。 You might think about which integers you need to check as divisors – certainly you don't need to go beyond the candidate you are checking, but how much sooner can you stop checking ? 你可能会想到你需要检查哪些整数作为除数 - 当然你不需要超越你正在检查的候选人,但你能早点停止检查多少?

  4. If the candidate is prime, print out some information so you know where you are in the computation, and update the state variables 如果候选者是素数,则打印出一些信息,以便您知道计算中的位置,并更新状态变量

  5. Stop when you reach some appropriate end condition. 达到适当的最终条件时停止。 In formulating this condition, don't forget that your program did not generate the first prime (2) . 在制定这个条件时, 不要忘记你的程序没有生成第一个素数(2)

It could look like this: 它可能看起来像这样:

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

First of all, from the vague description of your prime checking algorithm, it appears that you are checking every number up to the number that you are testing for primality. 首先,从您的主要检查算法的模糊描述中,您似乎正在检查每个数字,直到您正在测试素数的数字。 However, in reality you are only required to test up to the square root of that number. 但实际上,您只需要测试该数字的平方根。 A further optimization would be to remove all even numbers apart from two (you can do this by incrementing by twos from one and testing 2 separately), you end up with: 进一步的优化是删除除了两个之外的所有偶数(你可以通过从一个增加两个并分别测试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))

Then all you have to do is iterate through the numbers from 2 upwards checking if they are prime and adding one to your counter if they are. 然后,你所要做的就是从2向上遍历数字,检查它们是否为素数,如果它们是,则向你的计数器添加一个。 When you reach 1000 stop and output the number being passed to the isprime function. 当你达到1000停止并输出传​​递给isprime函数的数字。

Of course there are other more efficient methods, I personally prefer the Sieve of Atkin . 当然还有其他更有效的方法,我个人更喜欢AtveSieve But it would be up to you to implement that, my algorithm will serve your purposes. 但是由你来实现,我的算法将满足你的目的。

Edit: I noticed your comment that 'nothing is returning/happening' that would be due to the inefficiency of your algorithm, if you wait long enough you will get an answer. 编辑:我注意到你的评论“没有任何东西正在返回/发生”,这可能是由于你的算法效率低下,如果你等了足够长的时间,你会得到一个答案。 However, I do notice that you have no print statement in the code you provided, I'm hoping the code which your running has one. 但是,我注意到你提供的代码中没有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

This is a code I wrote for C++. 这是我为C ++编写的代码。 But the mentality must be the same. 但心态必须相同。

// 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.");}

This code below generates a list of primes upto 1 million. 下面的代码生成一个高达100万的素数列表。 Using that list, you can test for primes < 1 Trillion in a reasonably fast way. 使用该列表,您可以以合理快速的方式测试质量<1万亿。 This runs in a pretty fast time for 10-12 digit primes. 这对于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) )))]

You can increase the number of saved primes by extending the process above, but the program will take a long time (but one time only process). 您可以通过扩展上述过程来增加已保存素数的数量,但程序将花费很长时间(但仅限一次过程)。

In your code, you can test if 'test_num' is prime using the following... 在您的代码中,您可以使用以下内容测试'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