【问题标题】:Logic behind p / primes[i] >= primes[i] while finding prime numbers using arrayp / primes[i] >= primes[i] 背后的逻辑,同时使用数组查找素数
【发布时间】:2021-03-09 14:35:47
【问题描述】:

所以我是 C 的初学者,虽然我有使用 python 的经验,但我无法解决一个简单的问题。

如果我记得的话,在 Python 中查找素数是一项更容易的任务,但在 C 中做同样的事情时我遇到了困难。

所以从我一直关注的教程中,这是使用数组查找 3 到 100 之间的素数的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main()
{
    int p;
    int i;

    int primes[50] = { 0 };
    int primeIndex = 2;

    bool isPrime;

    // hardcode prime numbers
    primes[0] = 2;
    primes[1] = 3;

    for (p = 5; p <= 100; p = p + 2)
    {
        isPrime = true;

        for (i = 1; isPrime && p / primes[i] >= primes[i]; ++i)
            if (p % primes[i] == 0)
                isPrime = false;

        if (isPrime == true)
        {
            primes[primeIndex] = p;
            ++primeIndex;
        }
    }

    for (i = 0;  i < primeIndex;  ++i)
         printf("%i  ", primes[i]);

    printf("\n");
    return 0;
}

上面代码中的第一个for 循环是可以理解的,但第二个循环之后发生的事情让我很困惑。

第二个for循环中p / primes[i] &gt;= primes[i]条件背后的逻辑是什么?

例如,如果我按照循环采用 p = 5 并应用条件,它将是 5 / primes[1] &gt;= primes[1]

由于我们知道primes[1] = 3,这将变为5 / 3 &gt;= 3,它立即变为假。

请解释第一个 for 循环之后发生的情况

编辑:我已经添加了我可以自己做的python代码。为什么不能在 C 中做同样的事情:

lst = [2]
for i in range(3, 100):
     for j in range(2, i):
          if (i % j) == 0:
                break
     else:
          lst.append(i)

print(lst)

【问题讨论】:

  • 看起来像递归关系/动态规划示例
  • 这是检查primes[i]是否大于p的平方根,而不实际计算平方根。
  • @user253751 我们为什么要这样做
  • @Xtense:因为您永远不需要检查平方根以上的数字是否可整;如果它可以被平方根以上的数字整除,那么它也可以被您已经测试过的平方根以下的匹配数字整除。证明留作练习。
  • @Xtense:如果您不了解该教程,则需要阅读适当的 C 教程。这是一个简单的运算符。我们不能一次教你一个问题。

标签: arrays c for-loop


【解决方案1】:

内部for 循环尝试到目前为止找到的所有奇数素数,直到包括sqrt(p),而不实际计算sqrt(p)。一旦找到一个能将p 整除的素数,循环就会停止。它可能更具可读性:

    isPrime = true;
    for (i = 1; p / primes[i] >= primes[i]; ++i) {
        if (p % primes[i] == 0) {
            isPrime = false;
            break;
        }
    }

5 的情况下,to 循环不会开始,因为5 &lt; 3*35 是质数,7 也是如此:不需要测试来确定它的质数。

由于for 语句的else: 子句仅在循环正常退出时才执行,您的python 代码更加优雅。然而,当您测试所有数字时,python 版本中的算法效率要低得多,包括偶数和直到 i 的所有除数。对于100,差异几乎不明显,但对于更大的范围,将显示增加的复杂性。另请注意,lst 应初始化为lst = [2] 以使素数列表正确,您可以删除多余的if i &gt; 1:

【讨论】:

  • 对于9 检查9 % 3 == 0 是满意的,因此isPrime = False 所以我们继续下一个数字
  • 我认为在我的 python 代码中,我正在检查(0, i) 范围内的所有数字,因此不需要预定义条件,但在 C 代码中,由于某些数字会自动消除到预先指定的条件。也许它是时间复杂度的问题,C 代码做得更快,而 python 代码需要时间,因为每个数字都在循环中进行测试?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2021-05-09
  • 2022-01-10
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多