查找素数的Eratosthenes(筛子)算法终止条件解释

看书看到了Eratosthenes算法查找1~n中的素数,这也是招聘中常考的题目,其中的循环终止条件为n的开根号,想了很久没想懂,查了资料然后用实例慢慢跟感觉懂了一点,如果写得不对请指正。

算法思路:
从2开始(1既不是素数,也不是合数),建一个变量标记是否为素数,可以是boolean的数组或者Bitset;
将当前素数的倍数所对应的位置标记为非素数即可

循环的终止条件为n的开根号,因为n的开根号存在精确度问题,所以转换为i*i<=n,原因:
假设最接近n的开根号的整数为j
1.如果i小于j,这是需要进行循环判断的;
2.如果i大于j,则(n/i)小于j。这句话的意思可以解读为:
2.1.如果此时遍历的i是素数,则不判断也没关系
2.2.如果此时遍历的i不是素数,则它一定是前面j之前的某一个数的倍数
举例,查找1~100的素数,则循环到10即可,因为大于10的数:
1.如果这个数是素数,如11,则可以不遍历;
2.如果这个数不是素数,如20,100/20=5<10,所以20肯定是10以内某个数的倍数,我们在之前的循环操作中已经将其标记为非素数了,以此类推。又比如15,100/15=6<10等等。

附《java核心技术》中的代码

import java.util.*;
public class Sieve {
    public static void main(String[] args) {
        int n = 2000000;
        long start = System.currentTimeMillis();
        BitSet b = new BitSet(n+1);
        int count = 0;
        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++;
        }

        while(i <= n) {
            if(b.get(i)) count++;
            i++;
        }
        long end = System.currentTimeMillis();
        System.out.println(count + "primes");
        System.out.println((end - start) + "milliseconds");
    }
}

使用boolean作为标记的可以参考http://www.cnblogs.com/luzheng1/archive/2013/04/09/3009344.html
参考资料http://www.cnblogs.com/luluping/archive/2010/03/03/1677552.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值