我正在努力理解为什么代码不起作用。根据AND和OR https://en.wikipedia.org/wiki/Truth_table的真值表/逻辑门,我假设我将能够在middle
循环内使用if语句,使得for
可以找到质数,但在考虑负数时失败。
我知道,如果您将(p < 2 || p % i == 0)
取出并以if语句的形式写在此p < 2
循环之外,则它可以工作,但是如果for
位于{{1 }}-循环不起作用。为什么会这样?
p < 2
答案 0 :(得分:5)
因为p < 2
,所以从未执行for
循环的正文。确实:
for (int i = 2; i < p; i++) {
// ...
}
如果p = 2
,它将初始化i = 2
,然后检查失败的i < p
,因此将永远不会执行主体。它跳过for
循环,因此返回true
。
我们可以通过在for
循环之前(或之后)进行检查来修复它,甚至可以显着提高循环的性能:
public static boolean isPrime(int p) {
if(p <= 2) {
return p == 2;
}
if(p % 2 == 0) {
return false;
}
for (int i = 3; i*i <= p; i += 2) {
if (p % i == 0) {
return false;
}
}
return true;
}
对于所有小于false
的值,我们可以简单地首先返回2
,对于2则返回true
。此外,我们只需要迭代到√p ,因为如果除 p 的值 j 大于√p,那么会有一个较小的值 i = p /小于已经被检查的√p的j 。此外,我们只需要检查奇数个数字,因为2
的除法已经隐含了偶数。
答案 1 :(得分:1)
您可能想投资Math.abs(int)
:
public static boolean isPrime(int p) {
p = Math.abs(p);
for (int i = 2; i < p; i++) {
...
这将确保p
始终为非负数,并且您对循环行为的最初假设是合理的。