线性筛素数
怎么求素数?
一、普通方法
//定义法:质数只能被1和本身整除,最小质数为2
#include <iostream>
using namespace std;
bool prime(int num){
int i;
if(sum<2) return false;
if(num==2) return true;
for (i = 2; i < num/2; i++)
if (num % i == 0)
return false;
return true;
}
int main(){ //求1~100以内的素数
for(int i=1;i<=100;i++)
if(prime(i))
cout << i << endl;
return 0;
}
//计数法:质数只有两个因数
#include <iostream>
using namespace std;
bool prime(int num){
int i;
int count = 0;
if(sum<2) return false;
if(num==2) return true;
for (i = 1; i <= num; i++)
if (num % i == 0)
count++; // 统计能够整除自己的个数
if (count == 2) // 只有1和自己两个数可以整除自己
return true;
else
return false;
}
int main(){ //求1~100以内的素数
for(int i=1;i<=100;i++)
if(prime(i))
cout << i << endl;
return 0;
}
先来看这两个代码,时间复杂度非常高。另外判断方法还可以简化。m 不必被 2 ~ m-1 之间的每一个整数去除,只需被 2 ~
#include <iostream>
using namespace std;
bool prime(int sum){
if(sum<2) return false;
if(num==2) return true;
for(int i=2;i*i<=sum;i++)
{
if(x%i==0) return false;
}
return true;
}
int main(){ //求1~100以内的素数
for(int i=1;i<=100;i++)
if(prime(i)) cout << i << endl;
return 0;
}
二、埃式筛
这是什么?
埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于
#include <iostream>
using namespace std;
bool book[20005];
int main(){ //求1~100以内的素数
book[0]=book[1]=0;//不是必需的,因为后面程序直接从2开始筛
for(int i=2;i<=100;i++)
if(!book[i]){
for(int j=i+i;j<=100;j+=i)//用每一个素数一次去筛每一个数
book[j]=1;
}
for(int i=2;i<=100;i++)
if(!book[i]) cout << i;
return 0;
}
三、线性筛(欧拉筛法)
这又是什么?先上代码:
#include <iostream>
using namespace std;
bool book[20005];
int prime[20005],t=0;
int main(){ //求1~100以内的素数
for (int i = 2;i <= 100; i++)
{
if (!book[i])
prime[++t] = i;
for (int j = 1; j <=t && i*prime[j] <= 100; j++)
{
book[i*prime[j]] = 1;
if (i % prime[j] == 0)
break;
}
}
for(int i=2;i<=100;i++)
if(!book[i]) cout << i << endl;
return 0;
}
细心的同学就会发现,这就是优化的埃氏筛。先来看埃氏筛的问题:会将一个合数重复筛。举个例子,
#include <iostream>
using namespace std;
bool book[20005];
int prime[20005],t=0;
int main(){ //求1~100以内的素数
for (int i = 2;i <= 100; i++)
{
if (!book[i])//book[i]=0表示i是素数
prime[++t] = i;//这里的prime是一个栈,用来存放得到的素数
for (int j = 1; i*prime[j] <= 100; j++) //i*prime[j]的作用是控制筛查的范围,节约时间
{
if(j>t)//超过目前素数个数了
break;
book[i*prime[j]] = 1;//筛去当前数
if (i % prime[j] == 0)//i是prime[j]的整数倍时,说明 i * prime[j+1] 是 prime[j] 的整数倍,不需要现在筛出,因为在之后筛除过程中i * prime[j+1] 这个合数一定会被prime[j]筛除,这样节约时间
break;
}
}
for(int i=1;i<=t;i++)//依次输出,注意不要写成for(int i=2;i<=10;i++)
cout << prime[t] << endl;
return 0;
}
四、打表
这个就不用我说了吧。 可以参考我另一篇文章:https://www.cnblogs.com/include-blog/p/12365937.html。
---分割线--- 本文参考文章: https://blog.csdn.net/aiwangtingyun/article/details/79581598 https://blog.csdn.net/qq_39763472/article/details/82428602