简体   繁体   English

用Python枚举查找第N个素数

[英]Enumeration to find Nth prime with Python

I have decided it is about time that i should start learning to code. 我决定现在应该开始学习编码了。 I have some knowledge of HTML and CSS but i want to be able to develop for iOS. 我对HTML和CSS有所了解,但我希望能够为iOS开发。 I am aware i have a long way to go, but i aim to get there step by step. 我知道我还有很长的路要走,但我的目标是一步一步到达那里。

I'm working through the MIT Python course on iTunes U and I am stuck on the homework. 我正在通过iTunes U上的MIT Python课程进行学习,但仍无法完成作业。 I understand the concept of enumeration and testing every possible outcome to find the primes, however what i have tried so far has failed me. 我理解枚举的概念,并测试所有可能的结果以找到素数,但是到目前为止,我所做的尝试未能使我失败。 My closest attempt is the following. 我最接近的尝试如下。

# counting confirmed primes. For loop should do remainder tests on
# all testNumbers, unless caught by the if statements that rule out
# multiples of 2,3,5,7 to speed things up. divisor increments by one
# on those numbers that do not get pulled by qualifying if statements

testNumber = 2
confirmedPrime = 0

while (confirmedPrime < 1001):
        for divisor in range(1, testNumber+1):
                if (testNumber/2)*2== testNumber:
                        testNumber += 1
                elif (testNumber/3)*3 == testNumber:
                        testNumber += 1
                elif (testNumber/5)*5 == testNumber:
                        testNumber += 1
                elif (testNumber/7)*7 == testNumber:
                        testNumber += 1
                elif(testNumber%divisor == 0):
                        testNumber += 1
        confirmedPrime +=1
print testNumber

This however doesn't return the "7919" i am expecting but. 但是,这不会返回我期望的“ 7919”。 It returns "7507" So somewhere there are some composites slipping through the net. 它返回“ 7507”,因此在某处有一些复合材料通过网络滑落。

I have hunted through this site and not managed to solve it so I thought I would ask. 我已经在这个网站上搜寻并没有解决它,所以我想问一下。

A few bits are off here, so let's go step by step. 这里有些地方不对,让我们逐步进行。

You start by setting initial values, which is perfectly reasonable. 您首先要设置初始值,这是完全合理的。

testNumber=2
confirmedPrime = 0

Then you go into a while loop, continuing until the value of the variable confirmedPrime is has reached (ie is equal to or bigger than) 1001. I suppose your task is to find the 1000th prime, but doing it like this you're actually finding the 1001st, because the while loop continues until confirmedPrime has the value of 1001. Change it to 然后进入一个while循环,继续直到变量confirmedPrime的值达到(即等于或大于)1001。我想您的任务是找到第1000个素数,但是这样做实际上是找到1001个,因为while循环继续,直到confirmedPrime具有1001将其更改为价值

while(confirmedPrime < 1000):

You immediately go into another loop, and here comes the first problem, even though it isn't what's giving you the wrong answer. 您立即进入另一个循环,这是第一个问题,即使这不是给您错误答案的原因。

    for divisor in range(1, testNumber+1)
        if (testNumber/2)*2 == testNumber:
            ...

Doing the tests for multipliers of 2, 3, 5 and 7 inside the for loop doesn't make any sense, as you only have to to this once for each value of testNumber . for循环 for 2、3、5和7的乘法器进行测试没有任何意义,因为对于testNumber每个值只需执行一次即可。 So that part of the testing should be moved out of the for loop. 因此,该部分测试应移出for循环。

    if (testNumber/2)*2 = testNumber: # Why not use modulo here too for consistency?
        testNumber += 1
    elif ...
        ...
    else:
        for divisor in range(...):

The next part is testing for other, larger divisors. 下一部分将测试其他更大的除数。 You are testing divisors in the range 1 to testNumber+1 . 您正在测试1到testNumber+1范围内的除数。 I'm not sure why you're doing this, but it's not a good idea, as your modulo test will always return zero when you come to the second last iteration, testing testNumber%testNumber . 我不确定为什么要这样做,但这不是一个好主意,因为当您进行第二次迭代测试testNumber%testNumber时,模测试将始终返回零。 So you should change it to testNumber-1 , in fact you can stop when you have reached the square root of testNumber , but I'll leave it to you to figure out why. 因此,您应该将其更改为testNumber-1 ,实际上,您可以在到达testNumber平方根后停止,但是我将留给您找出原因。

Now comes the biggest problem: After the for loop is finished, you increment confirmedPrimes by 1 without actually checking if you found a prime or not. 现在到了最大的问题:后for循环结束后,你增加confirmedPrimes由1无需实际检查,如果你发现了一个黄金与否。 So, incrementing confirmedPrimes should only happen if none of the first tests were true and none of the "divisor tests" turned out to be true. 因此,增加confirmedPrimes如果没有第一次测试是真实的,并没有一个“除数测试”的竟然是真的应该只发生。

Rewritten using underscores instead of mixedCase (which is bad python mojo), consistent spacing etc: 使用下划线而不是mixedCase(这是不好的python mojo),一致的间距等进行了重写:

import math

test_number = 7       # Already know up to 7
confirmed_primes = 4  # Already know about 2, 3, 5 and 7

while confirmed_primes < 1000:
    test_number += 1

    if test_number % 2 and test_number % 3 and test_number % 5 and test_number % 7:
        is_prime = True

        for divisor in range(11, int(math.sqrt(test_number))+1):
            if test_number % divisor == 0:
                is_prime = False

        if is_prime:
            confirmed_primes += 1

print test_number

I don't understand exactly how your algorithm is supposed to find a prime number. 我不完全了解您的算法应该如何找到素数。

A number is said to be prime if it's only divisible by 1 or himself. 如果数字只能被1或他自己整除,则称该数字为质数。

Another definition is that a number is said to be prime if it's not divisible by any prime number smaller than it. 另一个定义是,如果一个数字不能被任何小于该数字的质数整除,则称该数字为质数。

This can be the base of your algorithm, speeding up the process by a lot. 这可能是您算法的基础,从而大大加快了处理速度。

def nth_prime(n):
    prime_list = []
    current = 2
    count = 0
    while(count < n):
        is_prime = True
        for prime in prime_list:
            if current % prime == 0:
                is_prime = False
                break
        if is_prime:
            prime_list.append(current)
            count += 1
        current += 1
    return current - 1

print nth_prime(1000) # => 7919

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM