zoukankan      html  css  js  c++  java
  • 筛选法求素数

    筛选法求素数

    这里说了常见的素数的求法

    但是,当求很多素数的时候就不合理了,每个数都有遍历

    今天发现这个筛选法很不错。

    求limit内的所有素数

    维基百科链接

    V1.0

    步骤:

    1:从2开始

    2:2是素数,去除2的倍数的数

    3:下一个数是3,则3是素数,去除所以3的倍数的数

    4:下一个数是5,则5是素数,去除是5的倍数的数

    《为什么不是4,4是2的倍数,已经去除》

    5:就这样一直遍历下去

    Java程序:

        int[] setPrime1(int limit){
            //prime 是保存的素数数组
            //notPrime 是保存的是否是素数的下标
            
            int prime[] = new int[limit];
            boolean notPrime[] = new boolean[limit];//默认 false
            // true  不是素数
            // false 是素数
            int p = 0;
            for(int i=2;i<limit;++i){
                if(!notPrime[i]){
                    prime[p++]=i;
                    for(int j=i+i;j<limit;j+=i){
                        notPrime[j] = true;
                    }
                }
            }
            return prime;
        }
    View Code

    V2.0

    思想:

    1.2是素数

    2.除以2余数是0的数不是素数,一次筛选

    3.2中没有把3筛选掉,同样,除以3余数是0的筛选掉

    4.2中已经把4筛选掉了,下一个数从5开始,

    5.重复上面过程

    Java程序:

        int[] setPrime2(int limit){
            int prime[]= new int[limit];
            boolean isPrime = true;
            //true 是素数
            //false 不是素数
            prime[0] = 2;
            int p =1;
            for(int i=3;i<limit;i+=1){
                isPrime = true;
                for(int j=0;j<p;j++)
                    if(i%prime[j]==0){
                        isPrime = false;
                        break;    
                    }
                if(isPrime==true)
                    prime[p++] =i;
            }
            return prime;
        }
    View Code

    V2.1

    在V1.0中定义两个数组,一个是存放素数的数组,一个是根据下标索引找素数的数组

    当在一般情况只需要第二个数组的时候,就可以优化程序

    这里有点不好说,看程序吧

    自己体会下就是了

    上界limit已经用sqrt(limit)附近的值判断了是否是素数

        boolean[] setPrime3(int limit){
            int prime[] = new int[limit];
            int p = 0;
            int subLimit = (int)Math.sqrt(limit)+1;
            boolean notPrime[] = new boolean[limit];
            for(int i=2;i<subLimit;++i){
                if(!notPrime[i]){
                    prime[p++]=i;
                    for(int j=i+i;j<limit;j=j+i){
                        notPrime[j] = true;
                    }    
                }
            }
            //notPrime 保存全部的素数信息。true对于的下标不是素数,false对于下标是素数
            //prime 只是保持根号limit内的素数,注意只有素数
            // 这里和setPrime有很大的类似的
            return notPrime;
        }
    View Code

    所有程序

    package codeforces;
    
    public class findprime {
        
        void run(){
            int limit=10000;
            int[] prime = setPrime2(limit);
            for(int i=0;i<limit;i++){
                System.out.print(prime[i]+" ");
                if(i%50==0)
                System.out.println();
                if(prime[i+1]==0) break;
            }
        }
        boolean[] setPrime3(int limit){
            int prime[] = new int[limit];
            int p = 0;
            int subLimit = (int)Math.sqrt(limit)+1;
            boolean notPrime[] = new boolean[limit];
            for(int i=2;i<subLimit;++i){
                if(!notPrime[i]){
                    prime[p++]=i;
                    for(int j=i+i;j<limit;j=j+i){
                        notPrime[j] = true;
                    }    
                }
            }
            //notPrime 保存全部的素数信息。true对于的下标不是素数,false对于下标是素数
            //prime 只是保持根号limit内的素数,注意只有素数
            // 这里和setPrime有很大的类似的
            return notPrime;
        }
        int[] setPrime2(int limit){
            int prime[]= new int[limit];
            boolean isPrime = true;
            //true 是素数
            //false 不是素数
            prime[0] = 2;
            int p =1;
            for(int i=3;i<limit;i+=1){
                isPrime = true;
                for(int j=0;j<p;j++)
                    if(i%prime[j]==0){
                        isPrime = false;
                        break;    
                    }
                if(isPrime==true)
                    prime[p++] =i;
            }
            return prime;
        }
        int[] setPrime1(int limit){
            //prime 是保存的素数数组
            //notPrime 是保存的是否是素数的下标
            
            int prime[] = new int[limit];
            boolean notPrime[] = new boolean[limit];//默认 false
            // true  不是素数
            // false 是素数
            int p = 0;
            for(int i=2;i<limit;++i){
                if(!notPrime[i]){
                    prime[p++]=i;
                    for(int j=i+i;j<limit;j+=i){
                        notPrime[j] = true;
                    }
                }
            }
            return prime;
        }
        
        public static void main(String[] args) {
            new findprime().run();
        }
    
    }
    View Code
  • 相关阅读:
    通配符^与not like 区别
    SQL语句
    身份证的性别验证(摘抄)
    基于VirtualBox虚拟机安装Ubuntu教程
    VMware手动添加centos7硬盘图文操作及分区超详细
    acl权限命令
    linux查看分区是否开启acl权限
    CentOS7上Docker简单安装及nginx部署
    Docker安装ngnix使用ping报错
    centos7安装mysql5.6
  • 原文地址:https://www.cnblogs.com/theskulls/p/4851786.html
Copyright © 2011-2022 走看看