Как создать 1000-е простое число в python?

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-м простым. Как я могу изменить свой код для этого. Заранее спасибо за помощь.

EDIT: теперь я понимаю, как это сделать. Но может кто-нибудь объяснить, почему следующий код не работает ? Это код, который я написал до того, как разместил здесь второй.

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

12 ответов


давайте посмотрим.

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 is не премьер. Если мы обнаружим, что это не простое число, мы должны (a) не распечатать, (b)не увеличить счетчик найденных простых чисел и (c) мы действительно должны вырваться из for loop - нет необходимости тестировать больше чисел.

кроме того, вместо проверки 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*q С p и q между 1 и n, то, по крайней мере один из p или q будет не больше квадратного корня из n: если бы они оба были больше, их продукт был бы больше, чем n.

так улучшенный код:

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) (как и в предыдущем коде), и посмотреть, как медленно он становится. Для 1000 простых чисел требуется 1,16 сек, а для 2000-4,89 сек (3000-12,15 СЭС). Но!--32-->С the sqrt для производства требуется всего 0,21 секунды 3000 простых чисел, 0,84 секунды для 10 000 и 2,44 секунды для 20 000 (заказы роста of ~ n2.1...2.2 и ~ n1.5).

алгоритм, используемый выше, называется судебного отделения. Есть еще одно улучшение, необходимое, чтобы сделать его оптимальный пробное подразделение, т. е. тестирование по простых только. Пример можно посмотреть здесь, который работает примерно в 3 раза быстрее, а при лучшей эмпирической сложности ~ n1.3.


то есть решето Эратосфена, который гораздо быстрее (для 20 000 простых чисел, 12x быстрее, чем" улучшенный код " выше, и намного быстрее, но после этого: его эмпирический порядок роста ~ n1.1, производства n простые числа, измеренные до n = 1,000,000 праймы):

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.5 x еще быстрее, в этом диапазоне, как здесь.


пара проблем очевидны. Во-первых, поскольку вы начинаете с 11, вы уже пропустили первые 5 простых чисел, поэтому счет должен начинаться с 5.

Что еще более важно, ваш основной алгоритм обнаружения просто не будет работать. Вы должны отслеживать все простые числа, меньшие, чем я, для такого упрощенного "сита Эратостанов", как простое обнаружение. Например, ваш алгоритм будет думать, что 11 * 13 = 143 является простым, но, очевидно, это не так.

PGsimple1 здесь является правильной реализацией того, что вы пытаетесь сделать здесь, но другие алгоритмы намного быстрее.


вы уверены, что правильно проверять первичные? Типичным решением является наличие отдельной функции "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

ваша логика не очень правильная. в то время как :

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 .


вот функция 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

Это, вероятно, быстрее: попробуйте разделить num от 2 до sqrt(num)+1 вместо диапазона (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

попробуйте это:

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
  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 является простым (чего нет)


Как насчет этого:

#!/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)

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.

вот еще одно представление:

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);

вот метод, использующий только циклы if & while. Это выведет только 1000-е простое число. Он пропускает 2. Я сделал это как набор задач 1 для курса OCW 6.00 MIT и поэтому включает только команды, преподаваемые до второй лекции.

prime_counter = 0  
number = 3  

while(prime_counter < 999):
    divisor = 2
    divcounter = 0
    while(divisor < number):
        if(number%divisor == 0):
            divcounter = 1  
        divisor += 1
    if(divcounter == 0):
        prime_counter+=1
    if(prime_counter == 999):
        print '1000th prime number: ', number
    number+=2

Я только что написал это. Он спросит вас, сколько простых чисел пользователь хочет видеть, в этом случае это будет 1000. Не стесняйтесь использовать его :).

# p is the sequence number of prime series
# n is the sequence of natural numbers to be tested if prime or not
# i is the sequence of natural numbers which will be used to devide n for testing
# L is the sequence limit of prime series user wants to see
p=2;n=3
L=int(input('Enter the how many prime numbers you want to see: '))
print ('# 1  prime is 2')
while(p<=L):
    i=2
    while i<n:
        if n%i==0:break
        i+=1
    else:print('#',p,' prime is',n); p+=1
    n+=1 #Line X

#when it breaks it doesn't execute the else and goes to the line 'X'