几种素数筛法:朴素筛 埃氏筛 线性筛 代码 以及运行时间对比
Published on 2022-11-17 23:04 in 暂未分类 with 林动

几种素数筛法:朴素筛 埃氏筛 线性筛 代码 以及运行时间对比

    之前在acm队训练的时候好像学了三种筛法现在只会朴素算法了。。
    占个坑后面复习后补完,不然就白学了。。

    突然想起来java的上下取整 开根号 绝对值 幂指函数 都不会,也在以后写在这吧 Math搞定一切

    朴素算法

    时间复杂度O(n^1.5)
    可以用来判断素数O(n^0.5),用来筛素数还是算了

    static void get_p1(int n)
    	{
    		for(int i=2;i<=n;++i)
    		{
    			boolean flag=true;
    			for(int j=2;j<=Math.sqrt(i);++j)//开根号下取整没问题
    			{
    				if(i%j==0)flag=false;
    			} 
    			if(flag)prime[cnt++]=i;
    		}
    	}
    

    2022.2.4回来填坑
    原来之前是学了3种,除了朴素算法用来判断素数,还有两种用来求N以内的素数,分别是埃氏筛和欧拉筛法(线性筛)


    埃氏筛

    时间复杂度o(nloglogn)

    略,直接学线性筛


    线性筛

    时间复杂度o(n)
    除了求N以内的素数还能求出N以内数的的最小质因子。

    由于空间限制,N最大只能是在10^7以内的范围

    static int prime[]=new int [N],cnt;
    	static int minp[]=new int [N];
    	static boolean st[]=new boolean [N];
    	
    	static void get_prime(int n)
    	{
    		for(int i=2;i<=n;i++)
    		{
    			if(st[i]==false)
    			{
    				minp[i]=i;
    				prime[cnt++]=i;
    			}
    			for(int j=0;prime[j]*i<=n;++j)
    			{
    				int t=prime[j]*i;
    				st[t]=true;
    				minp[t]=prime[j];
    				if(i%prime[j]==0)break;
    			}
    		}
    	}
    

    分解质因数:

    			int fact[]=new int [30];
    			int factnum[]=new int [30];
    			int k=0,tot=0;
    			
    			while(x>1)
    			{
    				int p=minp[x];
    				fact[k]=p;factnum[k]=0;
    				while(x%p==0)
    				{
    					x/=p;
    					factnum[k]++;
    					tot++;
    				}
    				k++;
    			}
    

    验证

    10^5以内的素数有9592
    10^6以内的素数有78498个
    10^7以内的素数有664579个


    对比

    计算10^6以内素数对比

    朴素筛法

    在这里插入图片描述

    线性筛法

    在这里插入图片描述


    计算10^7以内素数对比

    朴素筛法

    在这里插入图片描述

    线性筛法

    在这里插入图片描述

    测试程序

    import java.util.*;
    
    public class Main
    {
    	static int N=1<<20+5,n;
    	
    	static int prime[]=new int [N],cnt;
    	static int minp[]=new int [N];
    	static boolean st[]=new boolean [N];
    	
    	static void get_prime(int n)
    	{
    		for(int i=2;i<=n;i++)
    		{
    			if(st[i]==false)
    			{
    				minp[i]=i;
    				prime[cnt++]=i;
    			}
    			for(int j=0;prime[j]*i<=n;++j)
    			{
    				int t=prime[j]*i;
    				st[t]=true;
    				minp[t]=prime[j];
    				if(i%prime[j]==0)break;
    			}
    		}
    	}
    	static void get_prime2(int n)
    	{
    		for(int i=2;i<=n;++i)
    		{
    			boolean flag=true;
    			for(int j=2;j<=Math.sqrt(i);++j)//开根号下取整没问题
    			{
    				if(i%j==0)flag=false;
    			} 
    			if(flag)prime[cnt++]=i;
    		}
    	}
    	public static void main(String args[])
    	{
    		Scanner sc=new Scanner(System.in);
    		n=sc.nextInt();
    		long startTime = new Date().getTime();
    		get_prime(n);
    		long endTime = new Date().getTime();
    		for(int i=0;i<cnt;++i)System.out.println(prime[i]);
    		System.out.println(cnt);
    		System.out.println("本程序运行 " + (endTime - startTime)
                    + " 毫秒完成。" );
    	}
    }
    
    posted @   林动  阅读(140)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
    · Manus的开源复刻OpenManus初探
    · AI 智能体引爆开源社区「GitHub 热点速览」
    · C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
    · 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
    点击右上角即可分享
    微信分享提示