素数简介
素数(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
标签:判断,return,筛法,int,素数,倍数 来源: https://www.cnblogs.com/hulean/p/10799277.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。