【问题标题】:Generating large prime numbers in python在python中生成大素数
【发布时间】:2014-01-29 08:28:10
【问题描述】:

我似乎无法使用此代码生成随机素数,有人可以帮助我吗?

def RandomPrime():
  prime = False
  while prime == False:
    n = random.randint(10000, 100000)
    if n % 2 != 0:
      for x in range(3, int(n**0.5), 2):
        if n % x ==0:
          prime = False
        else:
          prime = True


  return n

【问题讨论】:

  • for 循环的每次迭代中,您通过设置 prime = Falseprime = True 忽略了早期迭代告诉您的内容,而不考虑 prime 曾经是什么。

标签: python random rsa primality-test


【解决方案1】:

想象一下如果range(3, int(n**0.5), 2) 中的最后一个 数字不是n 的整数除数会发生什么:

if n % x ==0:
    prime = False # not this
else:
    prime = True # this

所以即使之前的所有检查都评估了False,您仍将n 称为素数。解决此问题的代码最小更改是:

prime = prime and True # or 'prime &= True'

所以如果prime 已经 False,它仍然是False

但是,请记住,对于素数,如果 任何 这些检查是 False n 不是素数。您可以使用它和 Python 的 andall(它们是惰性评估的,即一旦找到 False 就不要继续检查)来更有效地实现:

def rand_prime():
    while True:
        p = randint(10000, 100000)
        if (r % 2 != 0 and
            all(p % n != 0 for n in range(3, int(((p ** 0.5) + 1), 2))):
            return p

为了获得更好的性能,请注意randrange 包含step 参数,就像range 一样,因此您可以跳过所有偶数(绝对不是素数!):

def rand_prime():
    while True:
        p = randrange(10001, 100000, 2)
        if all(p % n != 0 for n in range(3, int((p ** 0.5) + 1), 2)):
            return p

注意:在我看来,sqrt(n)(来自math)比n ** 0.5(尽管may or may not be more efficient)对其他技术含量较低的读者来说更清晰一些。

【讨论】:

  • 非常好的答案。有帮助
【解决方案2】:

查看选项卡:else 应该引用整个 for 循环,而不是 iF

def RandomPrime():
  prime = False
  while prime == False:
    n = random.randint(10000, 100000)
    if n % 2 != 0:
      for x in range(3, int(n**0.5), 2):
        if n % x ==0:
          break
      else:
          prime = True


  return n

【讨论】:

  • 考虑到循环中甚至没有break,这不是一个正确的答案。
【解决方案3】:

您的代码中有错误:

  1. “其他:”不正确;如果余数不为 0,则不能声明数为素数; 所有的remaiders应该是非零的
  2. int(n*0.5) 应为 int(n*0.5 + 1) 以防止舍入错误

可能的解决方案是

def RandomPrime():
  while True:
    n = random.randint(10000, 100000)

    if n % 2 == 0:
      continue;

    prime = True;

    for x in range(3, int(n**0.5 + 1), 2):
      if n % x == 0:
        prime = False;

        break; 

    if prime: 
      return n

【讨论】:

    【解决方案4】:

    正确的逻辑,你在设置Truen % x ! = 0 第一次:

      for x in range(3, int(n**0.5), 2):
        if n % x ==0:
          prime = False
        else:
          prime = True
    

    应该是:

      prime = False
      for x in range(3, int(n**0.5), 2):
        if n % x ==0:
          break
      else: 
        prime = True
    

    阅读break and continue Statements, and else Clauses on Loops

    编写等效代码的较短方式是(来自@Steve Jesso):

    prime = all(n % x != 0 for x in range(3, int(n**0.5), 2)
    

    【讨论】:

    • 一旦找到素数,OP 只想return,而不是return False - 它应该循环到一个新的随机数。
    • for 循环的else 在循环没有 中断时执行,因此您应该在其中设置prime = True。但实际上你可以用prime = all(n % x != 0 for x in range(3, int(n**0.5), 2) 替换整个东西。
    • @SteveJessop 是的,我更正了。还添加了您的建议谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2011-10-06
    • 2019-09-06
    相关资源
    最近更新 更多