java 求质数

在找工作的时候,笔试中经常能碰到求素数的编程题,或者是求多少以内的素数,或者是求多少以内的素数和。

 

这两天,我也对这个问题有了点兴趣,上网找了一些资料。整理之后,得到以下两个方法,个人觉得第二种算是很优化的了。

 

第一种方法:

        for (int i = 1; i < mList.size(); i++) {
            int a = mList.get(i);
            
            for (int j = 0; j < i; j++) {
                int b = mList.get(j);
                
                if (a % b == 0) {
                    mList.remove(i);
                    i--;
                    break;
                }
            }
        }

这种方法是先把数字都存到一个集合当中,然后过滤掉2的倍数以及3的倍数,然后遍历下去,当遍历到一个数的时候,看看集合当中位置在它之前的数,有没有能整除的,如果有的话,在集合中删除掉这个数,以此类推。

 

这种方法基本就是根据质数的概念来计算的,在效率上要低一些。

 

 

第二种方法

 

这种方法类似的在网上有很多,关键点就在于求一个数是否是质数,就先求出它的平方根,之后判断是否能被平方根以内的除1以外的某个自然数整除,如果有能整除的,那么这个数即为合数,没有即为质数。

 

    @Override
    public void makePrimeList()
    {
        for (int i = 0; i < mList.size(); i++) {
            Integer dividend = mList.get(i);
            Integer divisor = 2;
            int sqrt = (int)Math.sqrt(dividend);
            
            for (int j = 0; j <= sqrt && divisor <= sqrt; j++) {
                divisor = mList.get(j);
                
                if (dividend % divisor == 0) {
                    mList.remove(dividend);
                    i --;
                    break;
                }
            }
        }
    }

 

说一下平方根强转的问题,其实不强转当然也可以,不过我测试了几次,感觉强转的话,可能会稍微快点。

 

在我写的这个算法当中,加入了分解质因数的概念,即只判断是否能够被平方根之前的某个质数整除,这样的话,效率提高了很多。

 

我粗略的统计了下,求十五万以内的质数,用第一种方法,在我的电脑上用时差不多为27秒左右的时间,而用第二种方法用时为16秒左右的时间,差不多快了十秒。

 

 

修改1:

刚刚在CSDN上看到了这个算法,同样算15万以内的质数的个数,测试了几次。平均用时30毫秒左右,再看看自己上面的代码,真是太惭愧了。

    @Override
    public void makePrimeList()
    {
        int n = mNumber;
        BitSet b = new BitSet(n + 1);
        int count = 0;
        int i;

        for (i = 2; i <= n; i++)
            b.set(i);

        i = 2;
        while (i * i <= n) {
            if (b.get(i)) {
                count++;
                int k = 2 * i;
                while (k <= n) {
                    b.clear(k);
                    k += i;
                }
            }
            i++;
        }

        mList.clear();
        i = 2;
        while (i <= n) {
            if (b.get(i))
                mList.add(i);
            i++;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值