如何在python中生成第1000个素数?

时间:2013-03-14 02:27:26

标签: python primes

count = 0
i = 11

while count <= 1000 and i <= 10000:
    if i%2 != 0:
       if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
           continue
       else:
           print i,'is prime.'
           count += 1
    i+=1

我试图仅通过使用循环来生成第1000个素数。我正确地生成素数,但我得到的最后一个素数不是第1000个素数。我如何修改我的代码才能这样做。提前感谢您的帮助。

编辑:我现在明白了如何解决这个问题。但有人可以解释为什么以下代码不起作用?这是我在发布第二个之前写的代码。

count = 1
i = 3
while count != 1000:
    if i%2 != 0:
       for k in range(2,i):
          if i%k == 0:
            print(i)
            count += 1
            break
     i += 1

13 个答案:

答案 0 :(得分:7)

让我们看看。

count = 1
i = 3
while count != 1000:
    if i%2 != 0:
       for k in range(2,i):
          if i%k == 0:        # 'i' is _not_ a prime!
            print(i)       # ??
            count += 1     # ??
            break
     i += 1          # should be one space to the left,
                     # for proper indentation

如果i%k==0,那么i 是素数。如果我们发现它不是素数,我们应该(a)打印出来,(b)增加找到的素数的计数器和(c)我们确实应该从for循环中突破 - 无需再测试任何数字。

此外,我们可以从i%2开始增加2,而不是测试3,而是通过构造将它们变成奇数。

所以,我们现在有了

count = 1
i = 3
while count != 1000:
    for k in range(2,i):
        if i%k == 0:       
            break
    else:
        print(i)
        count += 1
    i += 2        

如果else循环过早破坏,for执行后for

它有效,但效果太难,所以速度要慢得多。它通过它下面的所有数字测试一个数字,但它足以测试它直到它的平方根。为什么?因为n == p*qp之间q1之间的np之间的数字qnn中的至少一个}将不大于from math import sqrt count = 1 i = 1 while count < 1000: i += 2 for k in range(2, 1+int(sqrt(i+1))): if i%k == 0: break else: # print(i) , count += 1 # if count%20==0: print "" print i 的平方根:如果它们都更大,则其乘积将大于range(2,i)

所以the improved code is

sqrt

尝试使用~ n2.1...2.2运行它(如前面的代码中所示),看看它有多慢。 1000个素数需要1.16秒,2000 - 4.89秒(3000 - 12.15秒)。但是 ~ n1.5生成3000个素数只需0.21秒,10,000点需要0.84秒,而~ n1.3与{~ n1.1 orders of growth相比需要2.44秒1}})。

上面使用的算法称为trial division。还需要进一步改进才能使其成为最佳试验部门,即仅通过 primes 进行测试。一个示例can be seen hereruns about 3x faster,并且n的经验复杂度更高。


然后有the sieve of Eratosthenes,其中is quite faster(对于20,000个素数,比上面的“改进代码”快12倍,然后更快):它的经验增长顺序为from math import log count = 1 ; i = 1 ; D = {} n = 100000 # 20k:0.20s m = int(n*(log(n)+log(log(n)))) # 100k:1.15s 200k:2.36s-7.8M while count < n: # 400k:5.26s-8.7M i += 2 # 800k:11.21-7.8M if i not in D: # 1mln:13.20-7.8M (n^1.1) count += 1 k = i*i if k > m: break # break, when all is already marked while k <= m: D[k] = 0 k += 2*i while count < n: i += 2 if i not in D: count += 1 if i >= m: print "invalid: top value estimate too small",i,m ; error print i,m ,用于产生{{1}}素数,测量到 n = 1,000,000素数):

{{1}}

真正无界的incremental, "sliding" sieve of Eratosthenes速度提高了约1.5倍,在此测试的范围内。

答案 1 :(得分:4)

有几个问题是显而易见的。首先,因为你从11开始,你已经跳过前5个素数,所以计数应该从5开始。

更重要的是,您的主要检测算法无法正常工作。你必须跟踪所有比我小的素数,因为这种简单的“Eratosthanes”筛子的质量检测。例如,你的算法会认为11 * 13 = 143是素数,但显然它不是。

PGsimple1 here是你正在尝试做的主要检测的正确实现,但其他算法要快得多。

答案 2 :(得分:3)

您确定要正确检查质数吗?一个典型的解决方案是拥有一个单独的“isPrime”功能,你知道它可以工作。

def isPrime(num):
    i = 0
    for factor in xrange(2, num):
        if num%factor == 0:
            return False
    return True

(有一些方法可以使上述功能更有效,例如只检查赔率,只有平方根以下的数字等)。

然后,要找到第n个素数,请计算所有素数,直到找到它为止:

def nthPrime(n):
    found = 0
    guess = 1
    while found < n:
        guess = guess + 1
        if isPrime(guess):
            found = found + 1
    return guess

答案 3 :(得分:2)

你的逻辑不是那么正确。 while:

if i%2 != 0:
    if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):

这不能判断一个数字是否为素数。

我认为你应该检查所有低于sqrt(i)的数字是否除以i。

答案 4 :(得分:1)

这是我在某处运行的is_prime函数,可能是在SO。

def is_prime(n):
  return all((n%j > 0) for j in xrange(2, n))

primes = []

n = 1
while len(primes) <= 1000: 
    if is_prime(n):
        primes.append(n)
    n += 1

或者如果你想在循环中全部使用它,只需使用is_prime函数的返回。

primes = []    
n = 1
while len(primes) <= 1000: 
    if all((n%j > 0) for j in xrange(2, n)):
        primes.append(n)
    n += 1

答案 5 :(得分:0)

这可能更快:尝试将数字从2分为sqrt(num)+1而不是range(2,num)。

from math import sqrt

i = 2 
count = 1

while True:
    i += 1
    prime = True
    div = 2
    limit = sqrt(i) + 1
    while div < limit:
        if not (i % div):
            prime = False
            break
        else:
            div += 1
    if prime:
        count += 1
    if count == 1000:
        print "The 1000th prime number is %s" %i
        break

答案 6 :(得分:0)

试试这个:

def isprime(num):
    count = num//2 + 1
    while count > 1:
        if num %count == 0:
            return False
        count -= 1
    else:
        return True

num = 0
count = 0
while count < 1000:
    num += 1
    if isprime(num):
        count += 1
    if count == 1000:
        prime = num

代码问题:

  1. 无需检查i&lt; = 10000。
  2. 你这样做

    if i%2 != 0:
        if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
    

    在这里,您不会检查该数字是否可以被大于7的素数整除。 因此你的结果:最有可能被11整除

  3. 因为2.你的算法说17 * 13 * 11是素数(它不是)

答案 7 :(得分:0)

这个怎么样:

#!/usr/bin/python

from math import sqrt

def is_prime(n):
    if n == 2:
        return True
    if (n < 2) or (n % 2 == 0):
        return False
    return all(n % i for i in xrange(3, int(sqrt(n)) + 1, 2))

def which_prime(N):
    n = 2
    p = 1
    while True:
        x = is_prime(n)
        if x:
            if p == N:
                return n
            else:
                p += 1
        n += 1
print which_prime(1000)

答案 8 :(得分:0)

n=2                         ## the first prime no.
prime=1                     ## we already know 2 is the first prime no.
while prime!=1000:          ## to get 1000th prime no.
    n+=1                    ## increase number by 1
    pon=1                   ## sets prime_or_not(pon) counter to 1
    for i in range(2,n):    ## i varies from 2 to n-1
        if (n%i)==0:        ## if n is divisible by i, n is not prime
            pon+=1          ## increases prime_or_not counter if  n is not prime
    if pon==1:              ## checks if n is prime or not at the end of for loop
        prime+=1            ## if n is prime, increase prime counter by 1
print n                     ## prints the thousandth prime no.

答案 9 :(得分:0)

这是另一个提交:

ans = 0;
primeCounter = 0;
while primeCounter < 1000:
    ans += 1;    
    if ans % 2 != 0: 
        # we have an odd number
        # start testing for prime
        divisor = 2;
        isPrime = True;
        while divisor < ans:
            if ans % divisor == 0: 
                isPrime = False;
                break;
            divisor += 1;
        if isPrime:             
            print str(ans) + ' is the ' + str(primeCounter) + ' prime';
            primeCounter += 1;
print 'the 1000th prime is ' + str(ans);

答案 10 :(得分:0)

这是一种仅使用&amp;而循环。这将只打印出第1000个素数。它跳过2.我做了这个麻省理工学院的OCW 6.00课程&amp;因此,只包括第二讲的教学内容。

{ Error: ENOENT: no such file or directory, access 'file:///home/callcenter1/BookGenerator/config/config.ini'
at Error (native)
at Object.fs.accessSync (fs.js:248:11)
at Object.fs.accessSync (ELECTRON_ASAR.js:420:27)
at getConfig (/home/callcenter1/BookGenerator/main.js:12:12)
at Object.<anonymous> (/home/callcenter1/BookGenerator/main.js:18:10)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
errno: -2,
  code: 'ENOENT',
  syscall: 'access',
  path: 'file:///home/callcenter1/BookGenerator/config/config.ini' }

答案 11 :(得分:0)

我刚刚写了这篇文章。它会问你有多少素数用户想看,在这种情况下它会是1000.随意使用它:)。

source

答案 12 :(得分:0)

这将是执行次数更少的优化代码,它可以在一秒钟内计算和显示10000个素数。 它会显示所有素数,如果只需要第n个素数,则在条件设置时进行设置并在退出循环后打印素数。如果要检查数字是否为质数,则只需将数字分配给n,然后删除while循环即可。  它使用素数属性 *如果数字不能被小于其平方根的数字整除,则为质数。 *我们可以检查35次迭代,从而结束循环,而不必进行检查直到结束(意味着1000次迭代以确定1000是否为质数), * break 如果循环在开始时被任意数除(如果是偶数循环,则循环将在第一次迭代时中断,如果被3再乘以2则可被整除),所以我们仅迭代到最后素数

请记住一件事,您仍然可以通过使用属性来优化迭代*如果一个数不能被素数小于的整数整除,则它是素数,但是代码太大,我们必须跟踪计算的质数,也很难找到一个特定的数是否是质数,所以这将是Best逻辑或代码

import math
number=1
count = 0

while(count<10000):
    isprime=1
    number+=1
    for j in range(2,int(math.sqrt(number))+1):
        if(number%j==0):
            isprime=0   
            break
    if(isprime==1):
        print(number,end=" ")
        count+=1