在第2章Schildt的Java初学者指南的自测中,有一个练习来编写一个程序来查找2到100之间的所有素数。
作者给出的正确答案如下:
class Prime {
puЬlic static void main(String args[]) {
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
}
}
我不明白两件事
1)第二个FOR循环的条件:
j <= i/j;
这是寻找素数的一种数学算法吗?
我的状况看起来像
j < i;
2)如果在第二个循环的条件下放置i <= j
而不是i < j
,则程序的输出将为空。为什么?
谢谢您的帮助!
第二个问题的说明:
当我解决此问题时,依靠素数定义的“ my”版本,我的代码如下:
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
请注意第二个循环的条件: 我<= j。小于或等于
如果您依赖素数的“我”定义,则条件中的等号应为
。尝试运行该程序。输出将为空。
但是,如果条件消除了等号for (j=2; j < i; j++)
,程序将正常运行。
原因是什么?
答案 0 :(得分:1)
让我们专注于这些for
循环。
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
第一个循环遍历您要测试的所有数字。简单易懂,它只是告诉“我要对2到100之间的所有数字执行以下测试”。
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
现在,此循环是纯数学运算。 在数学上,素数:
是大于1的自然数,不能由 将两个较小的自然数相乘。
(来源:维基百科)
因此,您遍历乘以i的所有数字。
但是您真的需要吗? 例如,如果i = 3 * 25,您是否需要一直迭代到25才能知道i不是质数?
答案显然不是,因为在测试了j = 3之后,您已经知道我是复合的。
在数学上,存在多种算法来检查数字是质数还是复合数,但是一种合理正确的方法是检查数字是否为any number between 2 and its own square root的倍数。您正在对此进行四舍五入。
由于上述原因,检查2和i之间的所有数字是多余的。
编辑:答案2)
使用
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
您要告诉编译器在j==i
上执行测试后停止循环 。当然,当j等于i时,(i%j)== 0始终为true。
用非信息学的术语,您正在检查一个数字是否由任何数字组成,不包括1,包括其本身,而您应该检查它是否由任何数字组成,但不包括1及其本身。
这是由于Java实现for
循环的方式:they stop when the middle condition evaluates to false.