题解:找出1-100中所有的素数(质数)
1、我们通常是遍历1-100,然后每个数字从2开始到根号i,只要取余等于0,则不是素数,否则就是素数来判断,像是这样:
bool judge(int x) //判断x是否为素数
{
for (int i = 2; i*i <= x; i++) //遍历2至根号x
{
if (x % 2 == 0) //若被整除,则返回假
return false;
}
return true; //退出循环 ,则返回真
}
在主函数中则是:
int main() //写出1-1000中所有素数
{
int n = 100;
for (int i = 2; i <= n; i++)
{
if(judge(i)) cout << i << " "; //是素数就打印
}
return 0;
}
但这样时间复杂度就达到了O(n²),数据超过1e5显然无法承受,这里介绍一种易理解的筛法优化时间:
一、埃式筛法
1、用一个数组储存所有的素数:
int ans[1001]; //储存素数
2、再用一个bool数组记录某个元素是否已经被筛去,初始全为false:
bool prime[1001] = {
false };
3、埃式筛法的思想为:从2-n遍历,每次找到记录为false的元素,就证明它则是素数(第一个是2,我们已知是素数了),第一次找到2后,筛掉所有2之后的倍数,数组记录为true,然后访问到数组值为false的元素3,因为3没有被刚才筛去,那么它一定也是素数,在筛去3之后的所有3的倍数……以此类推,具体图解如下:
4、每次找到素数后,则储存到素数数组中:
ans[index++] = i; //数组记录素数,再让下标+1
具体完整实现代码如下:
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
int index = 0; //素数数组下标
bool prime[1001] = {
false }; //记录是否被筛
int ans[1001]; //素数数组
int main() //写出1-1000中所有素数
{
int n = 100;
prime[1] = 1; //筛掉特殊的1
for (int i = 2; i <= n; i++)
{
if (prime[i] == false)
{
ans[index++] = i; //数组记录素数
for (int j = i + i; j <= n; j += i) //j+=i累加为i的倍数
{
prime[j] = true; //标记为已删除
}
}
}
for (int i = 0; i < index; i++)
{
cout << ans[i] << " ";
}
return 0;
}