每日小语:
失去了很多东西,才发现自己并非一无所有。——《神的记事本》
欧拉筛法内容:
欧拉筛法(Euler's Sieve)是一种高效的筛法算法,用于筛选出一定范围内的所有素数。该算法以数学家欧拉的名字命名,由欧拉首先提出。
欧拉筛法的主要思想是基于质数的倍数一定不是素数的性质。算法的步骤如下:
-
初始化一个布尔数组 primes[],将所有数都标记为素数(primes[i] = true)。
-
从2开始遍历到N,对于每个数
i
,如果它是素数(即 primes[i] = true),则将它的倍数(除了它本身)都标记为非素数(primes[j] = false)。 -
遍历结束后,primes[] 数组中为 true 的索引对应的数即为素数。
以下是一个使用欧拉筛法查找范围内的素数的示例代码:
#include <stdio.h>
#include <stdbool.h>
#define MAX_NUM 100
void eulerSieve(bool primes[], int n) {
// 将primes数组初始置为true,表示所有数都是素数
for (int i = 2; i <= n; ++i) {
primes[i] = true;
}
// 利用筛法,标记非素数
for (int p = 2; p * p <= n; ++p) {
if (primes[p] == true) {
// 将p的倍数标记为非素数
for (int i = p * p; i <= n; i += p) {
primes[i] = false;
}
}
}
}
int main() {
bool primes[MAX_NUM + 1];
eulerSieve(primes, MAX_NUM);
for (int i = 2; i <= MAX_NUM; ++i) {
if (primes[i]) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
在以上示例代码中,我们使用 eulerSieve
函数来执行欧拉筛法,接收一个布尔数组 primes
和一个整数 n
,并将 primes
数组中的元素设置为 true
或 false
,表示对应的数是否为素数。最后,我们遍历 primes
数组,输出为 true
的索引对应的值,即素数。
分步拆解:
1.首先,我们定义了一个布尔数组 primes
,数组大小为 MAX_NUM + 1
,其中 MAX_NUM
定义了要寻找素数的上限。
#define MAX_NUM 100
void sieveOfEratosthenes(bool primes[], int n) {
// 将primes数组初始置为true,表示所有数都是素数
for (int i = 2; i <= n; ++i) {
primes[i] = true;
}
2.然后,我们调用 sieveOfEratosthenes
函数来执行埃拉托斯特尼筛法。该函数接收一个布尔数组 primes
和一个整数 n
,并根据埃拉托斯特尼筛法的原理,将 primes
数组中的元素设置为 true
或 false
,表示对应的数是否为素数。
在 sieveOfEratosthenes
函数中,我们首先将 primes
数组初始化为 true
,表示所有数都是素数。
接下来,通过两重循环,我们遍历 p
从 2 到 sqrt(n)
,其中 p
表示当前的质数。对于每个质数 p
,我们将其倍数 p*p
、p*p + p
、p*p + 2p
等,都标记为非素数,即将对应位置的 primes
值设置为 false
。
// 利用筛法,标记非素数
for (int p = 2; p * p <= n; ++p) {
if (primes[p] == true) {
// 将p的倍数标记为非素数
for (int i = p * p; i <= n; i += p) {
primes[i] = false;
}
}
}
int main() {
bool primes[MAX_NUM + 1];
sieveOfEratosthenes(primes, MAX_NUM);
printf("2 ");
for (int i = 3; i <= MAX_NUM; i += 2) {
if (primes[i]) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
思考:
相同点:都是通过类似IsPrime这样的变量的改变值来判断。
不同点:欧拉筛法更省时省力,他抓住的问题的本质更细致。
欧拉筛法(Euler's Sieve)相较于其他素数筛法的优势主要在于其时间复杂度较低,具有以下几个好处:
1. 效率高:欧拉筛法在找出一定范围内的素数时具有较低的时间复杂度,约为 O(n) 或 O(nlog(logn))。相比于其他素数筛法,如试除法或埃拉托斯特尼筛法,欧拉筛法在大规模素数的筛选中速度更快。
2. 空间利用率高:与埃拉托斯特尼筛法不同的是,欧拉筛法仅使用一个布尔数组来标记素数和非素数,而不需要额外的存储空间。这使得欧拉筛法在处理大规模的素数筛选时所需的内存占用更低。
3. 可以高效地生成筛选后的素数列表:欧拉筛法通过标记非素数,最终留下来的为素数的数值。这使得我们可以高效地生成筛选后的素数列表,而无需进行额外的判断和操作。
4. 算法简单易实现:欧拉筛法的算法逻辑相对简单,易于理解和实现。通过两重循环,根据质数的倍数进行标记,即可找出范围内的素数。这使得欧拉筛法成为一种常用的素数筛选方法。
时间复杂度目前还不知道是什么,啊,还是得自己敲一遍。但我真的不想敲了呜呜,到饭点了,下次一定,撒花撒花。