素数和布尔逻辑
Primes and boolean logic
我想编写一个程序来查找从 b 到 a 的所有素数,所以我编写了这段代码(有效):
public static void main(String[] args) {
int a;
int c;
boolean isPrime;
a = 2;
c = 0;
while(a <= 100000 ){
isPrime = true;
for (int b = 2;b<a; b++){
c = a%b ;
//System.out.println(c);
if ( c == 0){
// this stores every not prime number
isPrime = false;
}
}
if (isPrime){
System.out.println(a);
}
a=a+1;
}
} // main end
接下来我尝试编写此代码的变体,但没有成功:
public static void main(String[] args) {
int q;
int w;
boolean isPrimeOne = false;
q = 2;
w = 0;
while(q <= 100){
isPrimeOne = false;
for (int d = 2; d<q; d++){
w = q%d;
if( w != 0 ){
isPrimeOne = true;
}
}
}
if(isPrimeOne){
System.out.println(w);
}
w = w+1;
}
在我看来,我的第一个和第二个代码非常相似。唯一的区别(我明白了)是我在第一个中将 isPrime
初始化为 true
,在第二个中初始化为 false
。
为什么第一个代码有效而第二个无效?
2个代码示例相似,但在isPrime
和isPrimeOne
变量的初始化和处理上相反。
第一个代码假定一个数是素数 (true
),直到找到一个因数。这证明该数字是合数,因此它被设置为 false
并保持这种状态直到循环结束。只需要一个因素就可以证明它是复合的。
但是,第二个代码假设一个数字是合数 (false
),直到找到一个不是因数的数字。但是仅仅因为一个数字被发现不是一个因素并不意味着它是质数。例如。 20
没有 3
作为一个因素,但它仍然是复合的。您正在打印 w
,余数,而不是 q
,您正在测试的数字。您正在递增 w
而不是 q
,这是在 while
循环之外而不是在 while
循环内。
这里有四个问题:
- 您递增的是
w
而不是 q
;
- 你在
while
循环之外递增它(检查你是否匹配花括号);
- 你在每个赋值中都反转了
isPrimeOne
相对于 isPrime
的逻辑,但在打印数字的检查中没有,所以你只输出非素数的东西;
- 你正在输出
w
而不是 q
。
我建议你尽量缩小变量的范围,没有必要在方法的开头声明所有的变量。如果您在 while
循环中声明 w
和 isPrimeOne
,这将防止您错误地在其他地方使用它们。
"It seems to me like my first and second code are very similar. the only difference (I see) is that I initialized is prime as true first, and is prime as false second."
其实不是。这两个程序有更多差异。只需对每一行进行简单比较,您就会发现它们。
"why does the first code work and the second code not work"
因为第一个程序遵循一个有效的算法来找出素数。第二个程序不遵循任何此类算法。有关详细信息,请参阅 rgettman 的回答。
我想编写一个程序来查找从 b 到 a 的所有素数,所以我编写了这段代码(有效):
public static void main(String[] args) {
int a;
int c;
boolean isPrime;
a = 2;
c = 0;
while(a <= 100000 ){
isPrime = true;
for (int b = 2;b<a; b++){
c = a%b ;
//System.out.println(c);
if ( c == 0){
// this stores every not prime number
isPrime = false;
}
}
if (isPrime){
System.out.println(a);
}
a=a+1;
}
} // main end
接下来我尝试编写此代码的变体,但没有成功:
public static void main(String[] args) {
int q;
int w;
boolean isPrimeOne = false;
q = 2;
w = 0;
while(q <= 100){
isPrimeOne = false;
for (int d = 2; d<q; d++){
w = q%d;
if( w != 0 ){
isPrimeOne = true;
}
}
}
if(isPrimeOne){
System.out.println(w);
}
w = w+1;
}
在我看来,我的第一个和第二个代码非常相似。唯一的区别(我明白了)是我在第一个中将 isPrime
初始化为 true
,在第二个中初始化为 false
。
为什么第一个代码有效而第二个无效?
2个代码示例相似,但在isPrime
和isPrimeOne
变量的初始化和处理上相反。
第一个代码假定一个数是素数 (true
),直到找到一个因数。这证明该数字是合数,因此它被设置为 false
并保持这种状态直到循环结束。只需要一个因素就可以证明它是复合的。
但是,第二个代码假设一个数字是合数 (false
),直到找到一个不是因数的数字。但是仅仅因为一个数字被发现不是一个因素并不意味着它是质数。例如。 20
没有 3
作为一个因素,但它仍然是复合的。您正在打印 w
,余数,而不是 q
,您正在测试的数字。您正在递增 w
而不是 q
,这是在 while
循环之外而不是在 while
循环内。
这里有四个问题:
- 您递增的是
w
而不是q
; - 你在
while
循环之外递增它(检查你是否匹配花括号); - 你在每个赋值中都反转了
isPrimeOne
相对于isPrime
的逻辑,但在打印数字的检查中没有,所以你只输出非素数的东西; - 你正在输出
w
而不是q
。
我建议你尽量缩小变量的范围,没有必要在方法的开头声明所有的变量。如果您在 while
循环中声明 w
和 isPrimeOne
,这将防止您错误地在其他地方使用它们。
"It seems to me like my first and second code are very similar. the only difference (I see) is that I initialized is prime as true first, and is prime as false second."
其实不是。这两个程序有更多差异。只需对每一行进行简单比较,您就会发现它们。
"why does the first code work and the second code not work"
因为第一个程序遵循一个有效的算法来找出素数。第二个程序不遵循任何此类算法。有关详细信息,请参阅 rgettman 的回答。