繁体   English   中英

在java中打印素数

[英]printing Prime numbers in 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."); 
        }
    }
}

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

内部(第二个)循环检查来自第一个循环的当前数字是否可以被任何东西整除。

此检查使用% (remainder): (i%j)==0i除以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 < ij*j<ij<i/j j足够大时, j*j可能会溢出,因此在最后一步中双方都被j除。


sqrt(i)的解释取自这里: 为什么我们要检查素数的平方根以确定它是否为素数?

如果i不是素数,则存在一些x使得i = x * j 如果xj都大于sqrt(i)x*j将大于i

因此,其中至少一个因子(x 或 j)必须小于或等于i的平方根,并且要检查i是否为素数,我们只需要测试小于或等于平方根的因子。

这是对埃拉托色尼筛法的改进。

首先,我将总结一下 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 到 100 的数字。

第二个循环尝试查找该数字是否可以被任何其他数字整除。 在这里,我们尝试将一个数字与一组数字(2 到 prime_index)相除。

假设数字是10 ,第一次迭代(j = 2)的素数索引是10/2 = 5 这意味着,如果数字10不能被 2 到 5 之间的任何数字整除,则它是质数。 它本身可以被2整除,使其成为非质数。

假设数字是 9,现在第一次迭代(j = 2)的素数索引是9/2 = 4 现在, 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; 
}

现在,这两种方法都将正确运行并打印素数。

但是,优化的方法将在第 10 次迭代时确定97是素数。

并且,未优化的方法将在第 48 次迭代中做出相同的决定。

希望,你现在明白了。

仅供参考:素数指数是我们用于计算的数字。 这样,如果一个数不能在 2 和派生的素数索引之间整除,则它是素数

公共类 PrimeNumber {

//check prime number
public static boolean prime(int number){
    boolean isPrime=true;

    for(int i=number-1;i>1;i--){

        if(number%i==0){
            isPrime=false;
            System.out.println(i);
            break;
        }
    }

   return isPrime;
}

public static boolean getPrimeUsingWhile(int number){
    boolean isPrime=true;
    Integer temp=number-1;
    while (temp>1){

        if(number%temp==0){
            isPrime=false;
            break;
        }

        temp--;
    }

    return isPrime;
}
//print primenumber given length
public static List<Integer> prinPrimeList(){

    boolean isPrime=true;
    List<Integer> list=new ArrayList<>();
    int temp=2;
    while (list.size()<10){

        for(int i=2;i<temp;i++){

            if(temp%i==0){
                isPrime=false;
                break;
            }else{
                isPrime=true;
            }

        }

        if(isPrime){list.add(temp);}
        temp++;
    }


    return list;
}


public static void main(String arg[]){

    System.out.println(prime(3));
    System.out.println(getPrimeUsingWhile(5));
    System.out.println(Arrays.toString(prinPrimeList().toArray()));
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM