Prime number sieve method (detailed explanation of Angstrom sieve and linear sieve)

The simplest way to find prime numbers is of course to traverse one by one. We traverse each number in turn, and then judge whether it is a prime number or not. So the core of the problem comes back to judging prime numbers, so how to judge whether a number is a prime number?

There is only one property of a prime number, that is, there are only two factors of 1 and itself , and we can only use this property to judge a prime number. So it can be imagined that if we want to judge whether n is a prime number, we can traverse from 2 to n-1. If none of the n-1 numbers can divide n, then n is a prime number. I remember correctly that it appeared in the exercises of the C language. In short, it is very simple, and it can be said to be the simplest algorithm.

Angstrom sieve method

The Eratosthenes algorithm we are going to introduce today is a method he invented to screen prime numbers. For convenience, we generally call it the Escherichia sieve or the sieve . The idea of ​​the Escherichia sieve method is very simple, that is to use the prime numbers that have been screened to filter all the numbers that can be divisible by it. These prime numbers are like a sieve to filter natural numbers, and the numbers left after being sieved are naturally numbers that cannot be divisible by the previous prime numbers. According to the definition of prime numbers, these remaining numbers are also prime numbers.

For example, if we want to filter out all prime numbers within 100, we know that 2 is the smallest prime number, we can use 2 to filter out all even numbers first. Then traverse back to 3, 3 is the first number left after being sieved by 2, and it is also a prime number. We then use 3 to sift out all numbers that are divisible by 3. After screening, we continue to traverse backwards. The first number encountered is 7, so 7 is also a prime number. We repeat the above process until the end of the traversal. At the end, we have all the prime numbers up to 100.

If you still don't quite understand, you can look at the following animation, which restores the whole process very clearly.

Time complexity is O(nlognlongn)

#include<iostream>
using namespace std;
const int N = 1e7;
int prime[N + 1];
bool visit[N + 1];
//素数筛
//埃式筛
int E_sieve(int n) {
	int k = 0;
	for (int i = 0; i < n; i++) visit[i] = false;
	// 1.普通
	/* for (int i = 2; i <= n; i++) {
		if (!visit[i]) {
			prime[k++] = i;
			for (int j = i * 2; j <= n; j+=i) { // i的倍数筛选调
				visit[j] = true;
			}
		}
	}*/
	//2.优化 有些数可能会被多筛几遍 这样会影响时间复杂度
	for (int i = 2; i * i <= n; i++)
		if (!visit[i])
			for (int j = i * i; j <= n; j += i) visit[j] = true;
	int k = 0;
	for (int i = 2; i <= n; i++) { // i * i 前面的合数被更小的素数划掉了
		if (!visit[i]) prime[k++] = i;
	}
	return k; // 1~n中的素数
}


int main() {
	return 0;
}

Euler Sieve

The Euler sieve method is also called the linear sieve method, which can sieve the prime numbers in 1~n in O(n) linear time.

For example, the composite number 6 can be crossed out by the prime numbers 2 and 3. At this time, we only need to clearly cross out the smallest prime number.

#include<iostream>
using namespace std;
const int N = 1e7;
int prime[N + 1];
bool visit[N + 1];
//素数筛
//埃式筛
int E_sieve(int n) {
	int k = 0;
	for (int i = 0; i < n; i++) visit[i] = false;
	// 1.普通
	/* for (int i = 2; i <= n; i++) {
		if (!visit[i]) {
			prime[k++] = i;
			for (int j = i * 2; j <= n; j+=i) { // i的倍数筛选调
				visit[j] = true;
			}
		}
	}*/
	//2.优化 有些数可能会被多筛几遍 这样会影响时间复杂度
	for (int i = 2; i * i <= n; i++)
		if (!visit[i])
			for (int j = i * i; j <= n; j += i) visit[j] = true;
	int k = 0;
	for (int i = 2; i <= n; i++) { // i * i 前面的合数被更小的素数划掉了
		if (!visit[i]) prime[k++] = i;
	}
	return k; // 1~n中的素数
}
bool vis[N + 1];
int euler_sieve(int n) {
	int cnt = 0;
	memset(vis, 0, 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; j++) {
			if (i * prime[j] > n) break; //越界的不需要了
			vis[i * prime[j]] = 1;//prime中全部的素数相乘一定式合数
			if (i % prime[j] == 0) break; //  每个合数只被最小质因子划掉 
		}
	}
	return cnt;
}
int main() {
	return 0;
}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/128633372