【问题标题】:Does anyone know why my program doesn't generate the correct amount of prime numbers?有谁知道为什么我的程序没有生成正确数量的素数?
【发布时间】:2021-08-03 13:33:55
【问题描述】:
print("Number of primes must be greater than 2")
number = int(input("Number of primes: "))
if number < 1:
    print("Invalid input")
    exit()
print(2)
print(3)
i = 0
no_primes = 2
while 1 < 2:
    m = 6 * i - 1
    n = 6 * i + 1
    if (2 ** m) % m == 2:
        print(m)
        no_primes += 1
    if no_primes == number:
        break
    if (2 ** n) % n == 2:
        print(n)
        no_primes += 1
    if no_primes == number:
        break
    i += 1

我的代码使用除了 2 和 3 之外的素数可以以 6n-1 或 6n+1 的形式表示的事实。我的 while 循环看起来很奇怪,但我不具备操作由两个循环组成的循环的专业知识变量(本例中为 no_primes 和 i)。当我生成前 1000 个素数时,它会跳过一些,以 7789 而不是 7919 结尾。有人知道为什么吗?另外,如果代码看起来多余,对不起。如果是,请说明我如何改进它

几周前我才开始使用 python,我想你应该知道

【问题讨论】:

  • 你为什么用while 1&lt;2而不是while True
  • 你能解释一下(2 ** n) % n == 2吗?这是n成为素数的充分条件吗?
  • @KotaMori 这是一个素数测试,称为费马小定理。从数学上讲,它总是有效的。但是,由于某种原因,它不适用于 Pycharm 上的大量数据
  • @Aqeel Fermat 的小定理指出,如果p 是素数,则遵循a**p % p == a。它确实 not 说明相反的情况,因此如果 a**p % p == a 这并不意味着 p 是素数 - 请参阅 341 作为示例。这意味着您的程序不仅打印素数,还打印费马伪素数。
  • 我不知道!谢谢@l4mpi

标签: python primes


【解决方案1】:

我不确定检查(2 ** m) % m == 2(2 ** n) % n == 2 是否会为您提供所有质数。 您是否与更暴力的方法进行了比较?

print("Number of primes must be greater than 2")
number = int(input("Number of primes: "))
if number < 1:
    print("Invalid input")
    exit()
elif number == 1:
    print(2)
else:
    print(2)
    print(3)
    prime_set = {2,3}
    i = 1
    while len(prime_set) < number:
        m = 6 * i - 1
        n = 6 * i + 1
        if all(m % p != 0 for p in prime_set):
            prime_set.add(m)
            print(m)
        if all(n % p != 0 for p in prime_set):
            prime_set.add(n)
            print(n)
        i+=1

这里是@Aqeel 为提高效率编辑的解决方案:

import time
import math
number = int(input("Number of primes: "))
t_0 = time.time()
if number < 1:
    print("Invalid input")
    exit()
elif number == 1:
    print(2)
else:
    print(2)
    print(3)
    primes = [2, 3]
    i = 1
    while len(primes) < number:
        prime_m = True
        prime_n = True
        m = 6 * i - 1
        n = 6 * i + 1
        sqrt_m = math.sqrt(m)
        sqrt_n = math.sqrt(n)
        for prime in primes:
            if prime > sqrt_m:
                break
            if m % prime == 0:
                prime_m = False
                break
        if prime_m:
            print(m)
            primes.append(m)
        if len(primes) == number:
            break
        for prime in primes:
            if prime > sqrt_n:
                break
            if n % prime == 0:
                prime_n = False
                break
        if prime_n:
            print(n)
            primes.append(n)
        i += 1
t_1 = time.time()
print(f"Found %s prime numbers in %ss" % (number, t_1 - t_0))

【讨论】:

  • 你的方法看起来很棒!非常感谢!
  • 该程序运行良好!我稍微修改了代码,使其检查生成的素数列表中小于或等于 sqrt(m) 或 sqrt(n) 的所有素数,以使其更快
  • 真的更快吗? sqrt 的计算本身对 cpu 有相当大的影响。但是,您可以使用 sqrt 的多项式近似...
  • 我对我的程序进行了计时,而且速度更快。不过,我会再检查一遍
  • 要生成前 10000 个素数,这里是平均时间。你的 - 5.69052624702s 我的 - 1.85073590279s 至于代码本身,我不知道如何方便地分享它,但它就在这个网站上 - pastie.org/p/2szQREFmjSHfJtFNyry7y3
【解决方案2】:

您的问题的答案是您正在打印非质数。

运行您的代码(输入 1000)会提供 1000 个数字,但使用适当的 is_prime() 函数检查这些数字会产生这些不是素数的数字:

341
1105
1387
1729
2047
2465
2701
2821
3277
4033
4369
4681
5461
6601

正如@Tranbi 所回答的,(2 ** m) % m == 2 不是测试素数的适当测试。查看this answer 以获得更好的解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-28
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多