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

    素数简介

    素数(prime number)又称质数,有无限个。
    素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。

    接下来介绍几种判断素数的方法:

    问法1:给定一个数n,判断n是不是素数

    一、暴力枚举

    枚举2~n-1分别当做除数,判断是否能整除,如果某个数能把n整除,那么就说明n不是素数,如果所有都不能整除,那么n就是素数。
    注:n=1或n=2时需要特判

    详见代码:

    bool work(int n)
    {
    	if(n==1)return false;
    	if(n==2)return true;
    	for(int i=2;i<=n-1;i++)
    	{
    		if(n%i==0)return false;
    	}
    	return true;
    }
    

    然而这样会很慢......

    二、优化过的暴力算法

    由于n至少会有一个约数在sqrt(n)中,所以我们可以直接枚举从2~sqrt(n),这样便会快不少。

    详见代码:

    bool work(int n)
    {
    	if(n==1)return false;
    	if(n==2)return true;
    	for(int i=2;i*i<=n;i++)//这里也可以写成i<=sqrt(n)
    	{
    		if(n%i==0)return false;
    	}
    	return true;
    }
    

    以上所说的算法只是用来判断单个素数的,但是若是要求1~n之间的素数该怎么办呢?

    还是暴力?
    不!
    要用到一个名叫“筛法”的东东

    三、埃氏筛法

    由于我们知道,2的任何倍数都不可能是素数,3的任何倍数不可能是素数,5的任何倍数不可能是素数......
    所以我们可以把素数的倍数全部筛掉。
    详见代码:

    /*
    vis用来判断有没有被筛掉,
    prime用来存储素数
    cnt代表素数总数
    */
    for(int i=2;i<=n;i++)
    {
    	if(vis[i]==1)continue;
    	prime[++cnt]=i;
    	for(int j=1;j*i<=n;j++)//筛掉素数的所有倍数
    	{
    		vis[j*i]=1;
    	}
    }
    

    但是以12为例
    12是2的倍数,被筛
    12是3的倍数,被筛++
    所以事实证明会有一些数被筛好多次
    那要怎么做到每个数只筛一次的线性复杂度呢?

    四、线性筛

    线性筛,又称欧拉筛
    欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

    /*
    vis用来判断有没有被筛掉,
    prime用来存储素数
    cnt代表素数总数
    */
    for(int i=2;i<=n;i++)
    {
    	if(!vis[i])prime[++cnt]=i;
    	for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
    	{
    		vis[i*prime[j]]=1;
    		if(i%prime[j]==0)break;
    	}
    }
    

    以上就是素数判断及筛法的总结,谢谢观看

    参考文献资料:
    https://www.baidu.com
    https://blog.csdn.net/qq_39763472/article/details/82428602

    最后打个小广告:
    https://www.luogu.org/blog/hulean0319/Game-ZMXY

  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/hulean/p/10799277.html
Copyright © 2011-2022 走看看