统计质数

原题

  Description:
  Count the number of prime numbers less than a non-negative number, n.

题目大意

  统计小于非负整数n的素数的个数。

解题思路

  使用见埃拉托色尼筛法。

埃拉托色尼筛法,是一种公元前250年由古希腊数学家埃拉托色尼所提出的一种简单检定素数的算法。

给出要筛数值的范围n,找出埃拉托色尼筛法以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个素数5筛,把5留下,把5的倍数剔除掉;不断重复下去......。

 

举例:求25以内的所有素数

(1) 列出2以后的所有序列:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

(2) 标出序列中的第一个素数,也就是2,划去2的倍数(用红色标出)序列变成:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

(3) 如果现在这个序列中最大数小于最后一个标出的素数的平方,那么剩下的序列中所有的数都是素数,否则回到第二步。本例中,因为25大于2的平方,我们返回第二步:

(4) 剩下的序列中第一个素数是3,再将主序列中3的倍数划出(红色),主序列变成:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

(5) 我们标出的素数有:2,3,当前25仍然大于3的平方,所以我们还要返回第二步:

现在序列中第一个素数是5,同样将序列中5的倍数划出,主序列成了:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

(6) 因为25等于5的平方,跳出循环.

结论:去掉红色的数字,2到25之间的素数是:2 3 5 7 11 13 17 19 23

 

下图中:

2是第一个标出的素数为红色,2的倍数为浅红色

3是第二个标出的素数为绿色,3的倍数为浅绿色

5是第三个标出的素数为蓝色,5的倍数为浅蓝色

2,3,5,加上剩余的灰色数字就是所求的素数

 

埃拉托色尼筛法

代码实现

算法实现类

public class Solution {

    public int countPrimes(int n) {

        if (n <= 1) {
            return 0;
        }

        // 默认所有的元素值都会设置为false
        boolean[] notPrime = new boolean[n];
        notPrime[0] = true;
        notPrime[1] = true;

        for (int i = 2; i * i < n; i++) {
            // 如果i是一个质数,i将i的倍数设置为非质数
            // 如是i是一个合数,则它必定已经设置为true了,因为是从2开始处理的
            if (!notPrime[i]) {
                for (int j = 2 * i; j < n; j += i) {
                    notPrime[j] = true;
                }
            }
        }

        // 统计质数的个数
        int result = 0;
        for (boolean b : notPrime) {
            if (!b) {
                result++;
            }
        }

        return result;
    }
}

转载于:https://my.oschina.net/u/2822116/blog/813514

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值