求素数(定义法,埃式法,欧拉法)
1:定义法
定义法对于大多数人来说是最容易理解的,也是最容易实现的:
定义法非常的简单,我们只需要多次循环,如果这个数可以被
除了1和自己本身整除的话,那他就不是一个素数。
代码如下(该代码只是判断是否为素数,不是选一个区间的所有素数)
2:埃式法选素数:
这种方法对于定义法来说难理解一些,但是他的算法时间复杂度要小一些;
该种选素数的方法步骤如下:
1:将该区间的所有数假设都为素数;
2:手动标记0和1不是素数;
3:从最小的数2开始循环,将2的倍数标记为不是素数;
4:然后区间内的最小数是一个素数;将最小数的倍数标记为不是素数;
5:依次循环就可以找出所有的素数:
代码如下:
#include<iostream> using namespace std; #define MAX_N 100000 bool is_prime[MAX_N];//用来判断是不是素数 int prime[MAX_N];//用来存放素数; int num;//统计素数的个数 int sieve(int n) { num=0; for(int i=1;i<=n;i++) is_prime[i]=true;//初始时假设所有的数都是素数; is_prime[0]=is_prime[1]=false;//规定0和1不是素数; for(int i=2;i<=n;i++)//由于0和1已经被归为不是素数,所以从2开始判断; { if(is_prime[i]) { prime[num++]=i;//如果是素数就存入数组中; for(int j=2*i;j<=n;j+=i) is_prime[j]=false;//将是该素数的倍数标记为不是素数; } } return num;//返回素数的个数; } void printf()//定义一个输出素数的函数; { for(int i=0;i<num;i++) cout<<prime[i]<<" "; cout<<endl; } int main() { int N; while(cin>>N) { cout<<sieve(N)<<endl; printf(); } }
3:欧拉式选素数:
跟埃式选素数差不多。
只是加了一个判断,将已经标记为素数的的倍数也标记。
代码如下:
#include<iostream> #include<cstring> using namespace std; int main() { int n, cnt = 0; int prime[100001];//存素数 bool vis[100001];//保证不做素数的倍数 cin>>n; memset(vis, false, sizeof(vis));//初始化 memset(prime, 0, sizeof(prime)); for(int i = 2; i <= n; i++) { if(!vis[i])//不是目前找到的素数的倍数 prime[cnt++] = i;//找到素数 for(int j = 0; j<cnt && i*prime[j]<=n; j++) { vis[i*prime[j]] = true;//找到的素数的倍数不访问 if(i % prime[j] == 0) break;//关键!!!! } } cout<<cnt; return 0; }