Java实现输出100000以内的质(素)数及算法布局优化

源代码 2024-9-15 07:42:29 161 0 来自 中国
输出100000以内的全部质数

质数:也叫素数,只能被1和他本身整除的天然数

最小的质数:2

方法一:服从很低

public class PrimeNumber {   public static void main(String[] args) {       boolean b = true;       //遍历100以内的天然数       for (int i = 2; i <= 100; i++) {           //j:被i除           for (int j = 2; j < i; j++) {               if (i % j == 0) {    //%是求模运算,即2%10=2,10%2=0,10%3=1。                   b = false;               }           }           if (b) {               System.out.print(i + " ");           }           b = true;       }   }}输出结果:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 实际上,上面的这种方法根本上是服从最低的。但由于100实在是太小了,盘算机的运算速率很快就能盘算出100以内的质数,以是如今我们不改变算法的布局,把100换成10万试试。

继续方法一:

public class PrimeNumber {    public static void main(String[] args) {        //获取当前时间隔断1970-01-01 00:00:00的毫秒数        long start = System.currentTimeMillis();        boolean b = true;        //遍历100以内的天然数        for (int i = 2; i <= 100000; i++) {            //j:被i去除            for (int j = 2; j < i; j++) {                if (i % j == 0) {    //%是求模运算,即2%10=2,10%2=0,10%3=1。                    b = false;                }            }            if (b) {                System.out.print(i + " ");            }            b = true;        }        //获取当前时间隔断1970-01-01 00:00:00的毫秒数        long end = System.currentTimeMillis();        System.out.println("\n泯灭时间:" + (end - start));  //6243毫秒    }}运行结果:

用以上这种方法,输出10万以内的质数居然用了6243毫秒,即6.3秒。在真实开发中。这么慢的速率是绝对不答应的。

以是接下来对这个算法举行优化
方法二:

优化一:利用break更快地跳出循环

public class PrimeNumber {    public static void main(String[] args) {        //获取当前时间隔断1970-01-01 00:00:00的毫秒数        long start = System.currentTimeMillis();        //遍历100以内的天然数        for (int i = 2;i<=100000;i++){            boolean b = true;            for (int j=2;j<i;j++){                if (i % j == 0){    //%是求模运算,即2%10=2,10%2=0,10%3=1。                    b = false;                    break;//优化一:只对本身非质数的天然数是有用的                }            }            if (b){                System.out.print(i+" ");            }        }        long end = System.currentTimeMillis();        System.out.println("\n泯灭时间:"+(end-start));  //优化一后:泯灭时间 619ms    }}这一次,我在最内层的if语句中参加了 break;

如许做的目标是让非质数更快的跳出循环,比如for循环到了100,此时i=100,进入第二个for循环,此时j=2,100%2=0,于是立即就break出了循环

运行结果:

2.png 可以看到,优化事后的速率立马就上来了,用时615毫秒。

方法三:

既然能对非质数举行优化,那是否可以对质数举行优化呢?固然可以

优化二:对本身是质数的天然数举行优化

public class PrimeNumber {    public static void main(String[] args) {        //获取当前时间隔断1970-01-01 00:00:00的毫秒数        long start = System.currentTimeMillis();        //遍历100以内的天然数        for (int i = 2;i<=100000;i++){            boolean b = true;            //优化二:对本身是质数的天然数是有用的            for (int j=2;j<Math.sqrt(i);j++){                if (i % j == 0){    //%是求模运算,即2%10=2,10%2=0,10%3=1。                    b = false;                }            }            if (b){                System.out.print(i+" ");            }        }        long end = System.currentTimeMillis();        System.out.println("\n泯灭时间:"+(end-start));  //优化二:122ms    }}运行结果:

可以看到,如今运行结果相比优化一又快了,用了122ms。

方法四:

最终优化:把优化一和优化二联合。

public class PrimeNumber {    public static void main(String[] args) {        //获取当前时间隔断1970-01-01 00:00:00的毫秒数        long start = System.currentTimeMillis();        //遍历100以内的天然数        for (int i = 2;i<=100000;i++){            boolean b = true;            //优化二:对本身是质数的天然数是有用的            for (int j=2;j<Math.sqrt(i);j++){                if (i % j == 0){    //%是求模运算,即2%10=2,10%2=0,10%3=1。                    b = false;                    break;//优化一:只对本身非质数的天然数是有用的                }            }            if (b){                System.out.print(i+" ");            }        }        long end = System.currentTimeMillis();        System.out.println("\n泯灭时间:"+(end-start));  //优化一加优化二:33ms    }}运行结果:

4.png 两种算法优化联合在一起结果不问可知,输出10万以内的质数仅用了33毫秒

试除法

int N = 29;                    //任意选择一个 N,以29为例int flag = 1;                  //flag记录 N 的属性。1 代表 N 是质数, 0 则代表不是。我们先默认它是for(int i = 2;i < N;i++){    if(N % i == 0){            //当 N 除以 i 的余数为 0,阐明 N 被 i 整除,即 N 为合数        flag = 0;        break;                 //由于 N 已经被证实是合数,不必要再继续运算了,跳出循环    }}//算法竣事,最终 flag 为 1 体现质数,flag 为 0 体现合数。 6.png
7.png int N = 29;                    int flag = 1;                   if(N % 2 == 0) flag = 0;                 //起首测试 N 是否是偶数else for(int i = 3;i * i < N;i += 2){    //与刚才差异的是,我们先从 3 开始,每次增长 2,一直                                         //到根号下 N 为止。如许我们的测试就在奇数中睁开    if(N % i == 0){                    flag = 0;        break;                     }}//算法竣事,最终 flag 为 1 体现质数,flag 为 0 体现合数。 8.png
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2025-3-15 06:27, Processed in 0.158458 second(s), 36 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表