【发布时间】:2021-10-29 06:50:27
【问题描述】:
所以从我一直关注的教程中,这是使用数组查找 3 到 100 之间的素数的代码。 第二个 for 循环中 p / primes[i] >= primes[i] 条件背后的逻辑是什么?
例如,如果我遵循 p = 5 的循环并应用条件,它将是 5 / primes[1] >= primes[1]:
因为我们知道 primes[1] = 3 这将变为 5 / 3 >= 3 立即变为假。 应该有一个测试来确保 p 的值不超过 primes[i] 的平方根 但是这里 p / primes[i] >= primes[i] 有 primes[i] 的平方根
enter code here
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;
}
【问题讨论】:
-
因为素数无论如何都是正数,所以在不等式两边乘以
primes[i],得到通常的检验primes[i]*primes[i] <= p。请注意,您不需要测试大于 sqrt(p) 的素数来测试 p 本身是否为素数。还要注意,中止这个内循环不会中止外循环,所以你将继续使用下一个更大的 p (7, 11, ... 直到 p 达到 100)。 -
a^2 <= b <=> a <= b/a <=> b/a >=a,谁发明了这种不可读的代码? -
旁注:我真的更喜欢
break循环而不是一次又一次地检查isPrime变量。如果您愿意申请goto(好吧,提前进行热烈讨论,但在我看来,这是一个有效应用程序的好例子)isPrime变量将完全过时...... -
@Dominique
a^2 <= b与a <= b/a相比,需要更大的整数类型(位数的两倍)来存储中间结果a^2。忽略这一点只会导致a的大值出现错误行为,这可能很难捕获和排除故障。因此,哪个版本“不可读”是值得商榷的。 -
@nielsen:您的反应就是发明源代码 cmets 的确切原因 :-)