Java在线笔试编程(4)----计算质数

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

**开源地址:https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB **

2.优化算法


private static int findZhiShu(int num) {

		int counts = 0;

		if (num < 2) {

			return counts;

		}

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

			boolean isZhiShu = true;

			double index=Math.sqrt(i);

			for (int j = 2; j <=index; j++) {

				if (i % j == 0) {

					isZhiShu = false;

					break;

				}

			}

			if (isZhiShu) {

				System.out.print(i + " ");//输出质数

				counts++;

			}

		}

		return counts;

	}

这里用到了 取平方的方法,缩小了查找的范围,原因如下:

循环到sqrt(N)即可,简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,

2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。

这个方法只能在百万级以下的数时,在3秒以内。

3.进一步优化的算法


private static int findZhiShu(int n){  

        boolean[] primes= filterNumber(n);  

        int num=0;  

        if(primes!=null){  

            for(int i=1;i<primes.length;i++){  

                if(primes[i]){  

              //    System.out.print(i+" "); //打印质数

                  num++;

                }  

            }  

        }  

       // System.out.println("一共有"+num+"个质数");  

         return num; 

    }  

 //筛选法  

    private static boolean[] filterNumber(int num){  

        if(num<=0){  

            System.out.println("范围必须大于0");  

            return null;  

        }  

        boolean[] isPrime = new boolean[num + 1];  

        isPrime[1] = false;  

        Arrays.fill(isPrime,2,num,true);  

        int n = (int)Math.sqrt(num);  

        for(int i=1;i<=n;i++){  

            if(isPrime[i]){  

                for(int j=i*i;j<=num;j+=i){  //2*i改为i*i可以避免重复赋值,效率提升了约6%

                    isPrime[j]= false;  

                }  

            }  

        }  

        return isPrime;  

    }  

用到的是 筛选法。依次剔除2的倍数,3的倍数,5的倍数…

这个算法可以有效的对付9位数(上亿),我计算机测试输入123456789时,花费时间在3秒以内,在计算大数时,效率大约是第二种的80-100倍左右.

毫无疑问,必须得选第三种方法。

参考代码如下:


import java.util.Arrays;

import java.util.Scanner;



public class Test0 {

   

	public static void main(String[] args) {

		Scanner mScanner = new Scanner(System.in);

		int len = mScanner.nextInt();

		int counts = 0;

		int array[] = new int[len];

		for (int i = 0; i < len; i++) {

			array[i] = mScanner.nextInt();

		}	

	//  long time0=System.currentTimeMillis();

		for (int i = 0; i < len-1; i++) {

			for (int j = i+1; j < len; j++) {

				counts += findZhiShu(array[j])-findZhiShu(array[i]);

			}

		}

	//	long time1=System.currentTimeMillis();

	

        System.out.println(counts);

    //  System.out.println((double)(time1-time0)/1000);

 



	}

	  //筛选法  

    private static boolean[] filterNumber(int num){  

        if(num<=0){  

            System.out.println("范围必须大于0");  

            return null;  

        }  

        boolean[] isPrime = new boolean[num + 1];  

        isPrime[1] = false;  

        Arrays.fill(isPrime,2,num,true);  

        int n = (int)Math.sqrt(num);  

        for(int i=1;i<=n;i++){  

            if(isPrime[i]){  

                for(int j=i*i;j<=num;j+=i){  //2*i改为i*i可以避免重复赋值,效率提升了约6%

                    isPrime[j]= false;  

                }  

            }  

        }  

        return isPrime;  

    }  

    

    private static int findZhiShu(int n){  

        boolean[] primes= filterNumber(n);  

        int num=0;  

        if(primes!=null){  

            for(int i=1;i<primes.length;i++){  

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值