【问题标题】:How to calculate first n prime numbers?如何计算前n个素数?
【发布时间】:2010-12-19 09:01:28
【问题描述】:

假设函数is_prime 可用。假设变量 n 与一个正整数相关联。写出计算前 n 个素数之和所需的语句。总和应与变量总计相关联。

注意:is_prime 将整数作为参数,当且仅当该整数是素数时才返回 True。 好吧,我写了is_prime这样的函数:

def is_prime(n):
    n = abs(n)
    i = 2
    while i < n:
        if n % i == 0:
            return False
        i += 1
    return True

但是除了 n=​​=0 之外它都有效。如何修复它以使其适用于每个整数? 我正在尝试找出如何编写函数来获取前 n 个素数之和以及如何修改我的 is_prime 函数的答案,该函数应该适用于所有可能的输入,而不仅仅是正数。

【问题讨论】:

  • 您应该只测试奇数(将 i 增加 2),将您的算法加速 2 倍...
  • @DevSolar:“不偶数”是“奇数”的奇数术语。代码必须检查 2,然后继续检查奇数;它也可以在 N 的平方根处停止,以实现另一个巨大的(大于 2 倍)加速。事实上,在检查 2 和 3 之后,您可以检查 6±1 的倍数(5、7、11、13 等)以获得更大的加速。
  • 第一段要求计算前 n 个素数之和的代码。它说“假设函数 is_prime 的可用性” 不要编写它。听起来你没有仔细阅读——或者你只是想弄清楚你需要如何写is_prime

标签: primes


【解决方案1】:

你的任务如下。

假设函数is_prime 的可用性。假设变量 n 与一个正整数相关联。写出计算前 n 个素数之和所需的语句。总和应该与变量 total 相关联。

正如 NVRAM 在 cmets 中正确指出的那样(似乎没有其他人注意到),问题是“假设函数 is_prime 的可用性”。

你没有来编写那个函数。您要做要做的是“编写计算前 n 个素数之和所需的语句”。

其伪代码类似于:

primes_left = n
curr_num = 2
curr_sum = 0
while primes_left > 0:
    if is_prime(curr_num):
        curr_sum = curr_sum + curr_num
        primes_left = primes_left - 1
    curr_num = curr_num + 1
print "Sum of first " + n + " primes is " + curr_sum

我想你会发现,如果你只是用你选择的语言来实现那个伪代码,那么你所要做的就是这些。

如果您正在寻找is_prime 的实现来测试您的分配,那么它的效率并不重要,因为无论如何您只会测试几个小值。考虑到将要使用它的代码的限制,您也不必担心小于 2 的数字。这样的事情是完全可以接受的:

def is_prime(num):
    if num < 2:
        return false
    if num == 2:
        return true
    divisor = 2
    while divisor * divisor <= num:
        if num % divisor == 0:
            return false
        divisor = divisor + 1
    return true

【讨论】:

    【解决方案2】:

    为什么不直接硬编码 i = 0 或 1 的答案?

    n = abs(n)
    i = 2
    if(n == 0 || n == 1)
       return true //Or whatever you feel 0 or 1 should return.
    while i < n:
        if n % i == 0:
            return False
        i += 1
    return True
    

    您可以通过省略一些数字来进一步提高算法的速度。此脚本仅检查 n 的平方根,因为 没有任何合数的因数大于其平方根 如果一个数具有一个或多个因数,则在该数的平方根之前会遇到一个。在测试大量数字时,这会产生很大的不同。

    n = abs(n)
    i = 2
    if(n == 0 || n == 1)
       return true //Or whatever you feel 0 or 1 should return.
    while i <= sqrt(n):
        if n % i == 0:
            return False
        i += 1
    return True
    

    【讨论】:

    • 一个在技术上不是素数。零绝不是质数。
    • 不正确地说“没有合数的因数大于其平方根” 123456 = 643 * 192 呢?一个因子小于平方根,另一个大于平方根 (351.363..)
    • 所以比平方根大的因子就不用分析了,因为还有一个比平方根小的因子,先找到那个因子来证明这个数是合数。跨度>
    • 确保你执行“i
    • 将“while i
    【解决方案3】:

    试试这个:

     if(n==0)
        return true
     else
        n = abs(n)
        i = 2
        while i < n:
            if n % i == 0:
                return False
            i += 1
        return True
    

    【讨论】:

      【解决方案4】:

      在您的问题陈述中,它说 n 是一个正整数。所以assert(n&gt;0) 并确保你的程序外循环永远不会is_prime() 带有负值也不为零。

      您的算法 - 对每个连续的 odd 数字进行试验划分(“奇数”对你来说是一个主要的加速) - 有效,但将是非常慢。查看prime sieve 以获得灵感。

      【讨论】:

        【解决方案5】:

        那么,当 n 为 0 或 1 时会发生什么?

        你有

        i = 2
        while i < n: #is 2 less than 0 (or 1?)
             ...
        return True
        

        如果您希望 n 的 0 或 1 返回 False,那么这是否表明您需要修改条件(或函数本身)以解决这些情况?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-27
          • 1970-01-01
          • 2012-03-26
          • 1970-01-01
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多