此Java代码在2-100之间打印出素数。
这很好用。
这段代码不是由我完成的。
但我想弄清楚这段代码发生了什么。
有人能告诉我第二次(for)循环后发生了什么吗?
class primenumbers{
public static void main(String args[])
{
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
// see if the number is evenly divisible
for(j=2; j <= i/j; j++)
// if it is, then its not prime
if((i%j) == 0) isprime = false;
if(isprime)
System.out.println(i + " is prime.");
}
}
}
答案 0 :(得分:0)
外(第一个)循环枚举[2,100]中的所有数字。
内(第二)循环检查第一个循环中的当前数字是否可以被任何东西分割。
此检查是使用%
(余数)(i%j)==0
完成的,当i
除j
的余数为0
时。根据定义,当余数为零时,i
可以j
分割,因此不是素数:isprime=false
。
您只需登记[2,i/j]
,因为您只需要查看sqrt(i)
(上一节中的说明)。
说过内循环可以重写为:
...
int s = sqrt(i);
for(j=2; j <= s; j++)
...
然而sqrt
比分割更贵,因此最好将j<=sqrt(i)
重写为(平方双方)j^2 < i
和j*j<i
以及j<i/j
。如果j
足够大,j*j
可能会溢出,因此双方在最后一步中被j
除以。
sqrt(i)
的解释来自Why do we check up to the square root of a prime number to determine if it is prime?
如果i
不是素数,则存在一些x
以便i = x * j
。如果x
和j
都大于sqrt(i)
,那么x*j
将大于i
。
因此,至少有一个因子(x或j)必须小于或等于i
的平方根,并检查i
是否为素数,我们只需要测试因子小于或等于平方根。
答案 1 :(得分:0)
这是对Eratosthenes筛子的修改。
首先,我将简要总结一下Eratosthenes的筛子,如果您已经知道这一点,可以跳到最后一段。 Eratosthenes算法的筛子循环通过一定的数字边界。 (说2 - 100)。对于它循环的每个数字,它取消多个,例如,因为2是素数(真),所有2的倍数都不是(它们是假的)。对于3,5等相同;并且算法跳过每个预定的非素数。因此,算法的模拟将是:
2 ---prime number... cancels out 4, 6, 8, 10, 12....
3 ---prime number... cancels out 6, 9, 12, 15, 18...
4 --- ALREADY CANCELLED OUT... Skip
5 --- prime number... cancels out 10, 15, 20, 25...
6 --- ALREADY CANCELLED OUT... Skip
未取消的数字因此是素数。您还可以阅读此内容以获取更多信息:http://www.geeksforgeeks.org/sieve-of-eratosthenes/
现在,根据您的问题,您的算法会遍历数字列表。对于每个数字(比如x),它检查循环通过(i / j)的任何先前数字是否是x的因子。将 i / j 用作第二个for循环的边界的原因是为了提高效率。如果您正在检查10(例如)是否为素数,则无需检查6是否为因子。您可以方便地停在n /(n / 2)。这就是那部分试图实现的目标。
答案 2 :(得分:0)
第一个循环只用于生成2到100之间的数字。
第二个循环尝试查找该数字是否可以被任何其他数字整除。在这里,我们尝试用一组数字(2到prime_index)来划分数字。
假设数字为10
,第一次迭代的主要索引为10/2 = 5
(j = 2)。这意味着,如果数字10
不能被2到5之间的任何数字整除,那么它就是素数。它可被2
整除,使其成为非素数。
假设数字是9,现在第一次迭代的主要索引是9/2 = 4
(j = 2)。现在,9 % 2
提供1作为提醒。因此,循环继续进行第二次迭代(j = 3)。现在主要指数是9/3 = 3
(注意这里主要指数值从4减少到3 )所以,现在如果数字不能被3
整除,那么它决定为素数。
因此,对于每次迭代,主索引都会减少,从而减少迭代次数。
Example for Number 97,
j = 2, prime index = 97/2 = 48 (no of iterations for loop)
j = 3, prime index = 97/3 = 32 (no of iterations for loop)
j = 4, prime index = 97/4 = 24 (no of iterations for loop)
j = 5, prime index = 97/5 = 19 (no of iterations for loop)
j = 6, prime index = 97/6 = 16 (no of iterations for loop)
j = 7, prime index = 97/7 = 13 (no of iterations for loop)
j = 8, prime index = 97/8 = 12 (no of iterations for loop)
j = 9, prime index = 97/9 = 10 (no of iterations for loop)
j = 10, prime index = 97/10 = 9 (loop exits as condition failed 10 <= 9 and declares 97 as a prime number)
现在,循环实际上需要10次迭代而不是建议的48次迭代。
让我们修改代码以便更好地理解。
public static void main(String args[]) {
// Number from 2 to 100
for(int i=2; i < 100; i++) {
if (isPrimeNumber(i)) {
System.out.println(i + " is prime");
}
}
}
现在,让我们看一下未优化的方法isPrimeNumberNotOptimized()
。
private static boolean isPrimeNumberNotOptimized(int i) {
for(int j=2; j <= i/2; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
另一种方法isPrimeNumberOptimized()
,用主要索引优化。
private static boolean isPrimeNumberOptimized(int i) {
for(int j=2; j <= i/j; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
现在,两种方法都会运行并正确打印素数。
但是,优化方法将决定97
是第10次迭代时的素数。
并且,非优化方法将在第48次迭代中决定相同。
希望,你现在明白了。
FYI: 主要指数是我们用于计算的数字。这样,如果一个数字在2&amp;之间不可分。派生的主要指数,它是素数