新浪微博 Github

The Sieve of Eratosthenes (素数筛选法)

问题描述

给定一个正整数 $n$,输出不超过 $n$ 的全部素数。

算法描述

  1. 写出$2\cdots n$所有的数。
  2. 计算出 $m=\sqrt{n}$ ,把不超过 $m$ 的所有素数的倍数(不能是素数本身)全部删除,剩下的就是 $2\cdots n$中的素数。

算法复杂度

$O(n)$

正确性证明

命题:给定一个合数x,一定存在不超过 $\sqrt{x}$ 的素数 P,且 $x \% p=0$。
证明:我们从1开始找合数,设 $x$ 为第一个不满足上述条件的合数。因为 $x$ 是一个合数,因此存在 $a$,使得 $x \% a=0$。
  (1)$a$是合数。因为$a$小于$x$,因此$a$满足:存在不超过 $\sqrt{a}$ 的素数$b$,且 $a \% b=0$。因为 $b<\sqrt{a}<\sqrt{x}$,因此 $x \% b=0$,与假设矛盾。
  (2)$a$是素数。因此 $a>\sqrt{x}$,因此 $x=ka$。
    1)$k$是合数。则同(1)的方法。
    2)$k$是素数。则 $k<\sqrt{x}$,因为假设 $k\ge \sqrt{x}$,则 $ka>x$,与假设矛盾。

算法实现

 1 public class Prime {
 2     public static int sieve(int n){
 3         boolean[] arr = new boolean[n+1];
 4         for(int i=0;i<arr.length;i++)
 5             arr[i] = true;
 6         int bound = (int)Math.floor(Math.sqrt(n));    //根号n
 7         for(int i=2;i<=bound;i++){
 8             if(arr[i]){
 9                 for(int j=2;j*i<=n;j++){
10                     arr[i*j] = false;
11                 }
12             }
13         }
14         int count = 0;
15         for(int i=2;i<arr.length;i++){
16             if(arr[i]) {
17                 count++;
18                 System.out.println(i);
19             }
20         }
21         return count;
22     }
23     public static void main(String[] args) {
24         sieve(100);
25     }
26 }
筛选法

 

孪生素数猜想

孪生素数:如果a,b是两个素数,且$a=b-2$,则称 $a$ 与 $b$ 是孪生素数。比如3与5是孪生素数。
孪生素数猜想:存在无穷多对孪生素数。
在2013年5月,张益唐证明了孪生素数猜想的弱化版本:存在无穷多对相差小于七千万的素数。

posted @ 2013-06-09 16:26  xiazdong  阅读(1045)  评论(2编辑  收藏  举报