在java中打印Prime数字

时间:2017-09-28 15:43:43

标签: java

此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."); 
        }
    }
}

3 个答案:

答案 0 :(得分:0)

外(第一个)循环枚举[2,100]中的所有数字。

内(第二)循环检查第一个循环中的当前数字是否可以被任何东西分割。

此检查是使用%(余数)(i%j)==0完成的,当ij的余数为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 < ij*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。如果xj都大于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;之间不可分。派生的主要指数,它是素数