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
  • 相关阅读:
    【NOIP2016提高组】 Day1 T3 换教室
    【NOIP2016 Day1 T2】天天爱跑步
    web@前端--html,css,javascript简介、第一个页面(常用标签简介)
    MySQL--视图view、触发器trigger、事务(start transaction)、存储过程(特殊的数据逻辑处理函数)、流程控制(if,case....)
    MySQL--pymysql模块
    MySQL--(了解)可能会用到的内置函数
    MySQL--详细查询操作(单表记录查询、多表记录查询(连表查询)、子查询)
    MySQL--表操作(约束条件foreign key关联表 多对1,多对多,1对1)
    MySQL--表操作(innodb表字段数据类型、约束条件)、sql_mode操作
    MySQL基本语句、存储引擎
  • 原文地址:https://www.cnblogs.com/bbbblog/p/4851786.html
Copyright © 2011-2022 走看看