埃式筛法筛选素数 PAT1013

内容摘要:

  1. 明确素数到底是啥数。
  2. 埃式筛法是干嘛用的。
  3. 利用java实现埃式筛法的思路。
  4. 利用埃式筛法解决PAT_1013_B 题。

素数(prime number)到底是啥数:

定义:

       在大于1的自然数中,除了1和它本身以外不能再被其他数所整除。

实例化定义:

  • 3是素数,因为它不可以被除了“1”以及自身“3”之外的数所整除。
  • 10不是素数,因为它除了“1”以及自身“10”之外,还可以被"2",“5”等数字所整除,所以他不是素数。我们也叫他“合数”(composite number)。

需要注意:

  • 2是最小的素数。
  • "素数"和"质数"是同一样东西。

埃式筛法是干什么用的:

  作用:

              从一堆自然数里面,找出这一堆自然数里面的所有的素数。

       实例化:

  •  前提:a[]={1,2,3,4,5,6,7,8,9...29},prime[]={}。
  •  通过:  埃式筛法从数组a中筛选出所有的素数,并且把他们放进数组prime[]中。
  •  得到:prime[]={2,3,5,7,11,13,19,23,29}。

利用java实现埃式筛法的思路:

  首先明确算法主要的依据以及两个前提:

       主要的依据:任何一个合数,一定有比他小的素数因子。(大家可以利用小时候学的分解自然数的过程去理解一下这句话)

  • 默认2是已知的最小的素数
  • 任何素数的倍数都不是素数,比如已经"2"是素数,但是2的倍数,例如4,6,8,10,12...都一定不是倍数,因为"倍数"就是可以整除这个数的因子。               

对范围在2~100的数应用埃式筛法筛选出这里面的所有素数的过程:

装有2~100自然数的数组的最初状态。

   

2是素数,标记所有2的倍数。从4开始。

3在上一步没有被标记,所以3是素数。标记所有3的倍数,从9开始。

5是素数,标记所有5的倍数,从25开始

7是素数,标记所有7的倍数,从49开始

11的平方,超过了100,在数组里面所有没有被标记的数字都是素数 

最终得到的结果

 转化成代码的几个关键部分:

1.利用boolean类型的素组去标记非素数

2.算法由嵌套的两层循环组成

  • 外层:寻找未被标记的元素(素数)
  • 内层:把素数的倍数标记为合数(composite)

java代码(找出自然数upperBound内,包括upperBound的所有的素数,并且把它们输出)

 1  public void runEratosthenesSieve(int upperBound) {
 2       int upperBoundSquareRoot = (int) Math.sqrt(upperBound);
 3     /*这里取平方是因为通过数学推理可以知道只需要判断到upperBound的上界即可。
 4       第一次写的读者可以把循环的次数设置成upperBound,便于理解*/
 5       boolean[] isComposite = new boolean[upperBound + 1];
 6    //这个boolean类型的数组是为了标记upperBound以内的自然数
 7 
 8       for (int m = 2; m <= upperBoundSquareRoot; m++) {
 9             if (!isComposite[m]) {
10                   System.out.print(m + " ");
11                   for (int k = m * m; k <= upperBound; k += m)
12                         isComposite[k] = true;
13             }
14       }
15       for (int m = upperBoundSquareRoot; m <= upperBound; m++)
16             if (!isComposite[m])
17                   System.out.print(m + " ");
18 }

 

题意:输出第M~N个素数。

思路:利用筛法把素数表打印至第N个素数,然后按格式输出。

java代码

 1 class Prime1{
 2     private int maxn =100010;
 3     private int a[] =new int[maxn];
 4 
 5     void isPrime(int n){
 6         boolean flag[] = new boolean[maxn];
 7         int index=0;
 8         for(int i=2;i<maxn;i++){
 9             if(index>=n) break;//无需找出第n个素数后的素数
10             if(! flag[i]){
11             a[index]=i;
12             index++;
13                 for (int j=2*i;j<maxn;j+=i){
14                     flag[j]=true;
15                 }
16             }
17         }
18     }
19 
20     void outprint(int m,int n){
21         int count=0;
22         isPrime(n);
23         for(int i=m-1;i<n;i++){
24             if(count%10!=0&&i!=n-1){
25                 System.out.print(a[i]+" ");
26             }else{
27                 System.out.println();
28             }
29         }
30     }
31 }

              

    

猜你喜欢

转载自www.cnblogs.com/HelloTum/p/9025584.html
今日推荐