埃氏筛和欧拉筛
1.埃氏筛
思路:将所求范围内所有的数定义为素数,从最小的真实素数(即2)开始,将其倍数筛选出来定义为非素数,最后剩下的被定义为素数的数便是给定范围内所有的素数。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 bool prime[1000]; 4 int n; 5 void getprime() 6 { 7 for(int i=2;i<=n;i++) 8 prime[i]=true; 9 for(int i=2;i<=sqrt(n);i++) 10 { 11 if(prime[i]){ 12 for(int j=i*i;j<=n;j+=i) 13 { 14 prime[j]=false; 15 } 16 } 17 } 18 } 19 int main() 20 { 21 ios::sync_with_stdio(false); 22 cin.tie(0),cout.tie(0); 23 cin>>n; 24 getprime(); 25 for(int i=1;i<=n;i++) 26 { 27 if(prime[i]) 28 cout<<i<<' '; 29 } 30 return 0; 31 }
2.欧拉筛
当数据过多的时候埃氏筛的弊端便体现了出来,即他会重复标记一个数不是素数的倍数,即当素数是2时18会被标记为不是素数,而当素数为3时18会再次被标记为不是素数,因此会导致数据过大时重复次数过多时间过长的问题。而这时欧拉筛便很好的解决了这一弊端。
思路:其实欧拉筛并没有那么繁琐,大致就是从2开始剔除倍数,但是省略了重复标记的过程,具体看代码。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+1; 4 typedef long long ll; 5 ll n,k; 6 bool a[maxn];//判断是否是素数。 7 int prime[maxn];//用来存素数。 8 void getprime() 9 { 10 a[0]=true,a[1]=true;//1和0不是素数,直接标记即可。 11 for(int i=2;i<=maxn;i++) 12 { 13 if(!a[i])//如果没有被标记为true,就是素数。 14 prime[++k]=i; 15 for(int j=1;j<=k;j++) 16 { 17 if(i*prime[j]>maxn) 18 break; 19 a[i*prime[j]]=true;//用素数一次乘i,结果标记为true。 20 if(!i%prime[j])//节省时间最关键的一步,即只标记一次。 21 break; 22 } 23 } 24 } 25 int main() 26 { 27 ios::sync_with_stdio(false); 28 cin.tie(0),cout.tie(0); 29 cin>>n; 30 getprime(); 31 for(int i=1;i<=n;i++) 32 cout<<prime[i]<<' '; 33 return 0; 34 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析