【数论】素数 埃氏筛法c++代码分析(逐句分析)

在有一些题目中,我们需要用到素数。而我们判断素数最简单的方法就是用这个数依次试着从2到他本身减一暴力取余,如果没有有一个数取余后得0则代表这个数是素数。

代码如下

bool pri(int n)
{
	for(int i=2;i

当题目简单的时候,我们当然可以用这种方法来判断素数。但显然,在某些充满了出题人恶意的题目中,这种暴力搜索是会超时的,并且我们发现如果我们需要在题目中重复用到素数,这种暴力的方法效率奇低,在解题时显然不是我们首选的方法。

因此,在这里我们需要介绍一种算法,埃氏筛法。通过埃氏筛法,我们可以通过一次筛选存下我们需要的范围的所有素数然后在接下来的解题中用到。

埃氏筛法的意思就是,每找到一个素数,就删去所给数据范围内的所有这个素数的倍数,然后在删完一轮数后留下的第一个数就一定是下一个素数。比如我们给一个范围2到120,我们知道最小的素数是2,然后删除范围内所有2的倍数,删完后剩下的第一个数就是3,3就是下一个素数,然后我们再把数据范围内所有3的倍数全部删除…全删完后留下来的数字就是我要找的范围内的所有素数。

了解了基本概念后,让我们来对照代码来进行分析

上代码!!!!

#include
#define ll long long
using namespace std;

const ll X = 10000005;
bool isp[X];  //i代表数字,isp[i]=1就代表i不是素数
ll pri[X],cnt=0;  //pri[i]代表第i个素数,用来存下素数,cnt是计数工具变量

void table()  //定义打表函数table
{
	isp[0] = isp[1] = 1;  //排除0和1
	for (ll i = 2; i < X; i++)
	{
		if (isp[i] == 0)  //每次寻找没有被筛掉的第一个数,每筛一次确定一个素数
		{
			pri[cnt++] = i;  //记录下被确定的第cnt个素数
			for (ll j = i + i; j < X; j += i)  //i确定了一个素数i那么i的倍数全要被筛掉
			{
				isp[j] = 1;  //等于1就代表被筛掉了
			}
		}
	}
}

int main()
{
	ll n;
	cin >> n;
	table();
	for (ll i = 0; pri[i] <= n; i++)//输出不大于n的所有素数
	{
		cout << pri[i] << ' ';
	}
	return 0;
}


输入样例

120

输出样例

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113

搞定了基本概念后我们来找个题目练练手吧找素数

算法提高 找素数
描述

  给定区间[L, R] , 请计算区间中素数的个数。

输入
输入描述:
  两个数L和R。
输入样例:
2 11

输出

输出描述:
  一行,区间中素数的个数。
输出样例:
5

AC代码如下

#include

#define ll long long
using namespace std;

ll l, r,ans;
const ll X = 10000005;
ll ispr[X];//质数表
bool che[X];//0代表是,1代表不是
bool b[X];//b[i]代表从l到r的质数合数情况判断
ll cnt=0;
void table()//打表函数
{
	ispr[0] = ispr[1] = 1;//0和1都不是质数
	for (ll i = 2; i < X; i++)
	{
		if (che[i] == 0)
		{
			ispr[cnt++] = i;
			for (ll j = i + i; j < X; j += i)
			{
				che[j] = 1;
			}
			ll f = (i - l % i)%i;//f代表从l到r的第几个数(这里f=0代表第一个数),寻找从l到r的第一个能整除刚找到的质数i
			ll x = l + f;//x代表这个数是几
			if (x == i)//如果x就是质数本身的话是不用被筛掉的
				f += i;
			for (ll j = f; j < r - l + 1; j += i)//把从l到r是质数i的倍数的数全筛掉
				b[j] = 1;
		}
	}
}

int main()
{
	cin >> l >> r;
	table();
	for (ll i = 0; i < r - l + 1; i++)
	{
		if (b[i] == 0)ans++;
	}
	cout << ans;
	return 0;
}


你可能感兴趣的:(笔记,c++,算法,素数筛)