Bootstrap

素数筛法C++

众所周知,素数筛法许多种,今天我来比较时间。都是1e7以内的素数。

话不多说,开始比较(有错请指出):

1.暴力法:

一个一个枚举

#include<bits/stdc++.h>
using namespace std;

bool isPrime(long long num) {
	for(long long i = 2; i <= num; i++) {
		if(num % i == 0) {
			return false;
		}
	}
	if(num < 2) {
		return false;
	}
	return true;
}

int main() {
	int cnt = 0;
	for(int i = 1; i <= 1e7; i++) {
		if(isPrime(i) == 1) {
			cnt++;
		}
	}
	cout << cnt << endl;
	return 0;
}

这个太慢了,大约是1600万秒(≈185天),效率最低。 

2.优化版:

由一个一个枚举变成了从一开始到sqrt(i)。

#include<bits/stdc++.h>
using namespace std;

bool isPrime(long long num) {
	for(long long i = 2; i * i <= num; i++) {
		if(num % i == 0) {
			return false;
		}
	}
	if(num < 2) {
		return false;
	}
	return true;
}

int main() {
	int cnt = 0;
	for(int i = 1; i <= 1e7; i++) {
		if(isPrime(i) == 1) {
			cnt++;
		}
	}
	cout << cnt << endl;
	return 0;
}

这个5秒多,还是太低。

3.埃拉托斯特尼筛法(埃氏筛法)时间复杂度:O(nlogn)

     思想:

  1. 初始化一个布尔数组,表示每个数是否为素数,初始值为True。
  2. 从2开始遍历到n​,对于每个素数p,将其倍数p×k(其中k>1)标记为非素数。
  3. 遍历完整个范围后,未被标记的数即为素数

     我这个不是按上面来的

#include<bits/stdc++.h>
using namespace std;

bool isPrime(long long num) {
	for(long long i = 2; i * i <= num; i++) {
		if(num % i == 0) {
			return false;
		}
	}
	if(num < 2) {
		return false;
	}
	return true;
}

int main() {
	int cnt = 0;
	for(int i = 1; i <= 1e7; i++) {
		if(isPrime(i) == 1) {
			cnt++;
		}
	}
	cout << cnt << endl;
	return 0;
}

0.5秒多,还可以。

4.欧拉筛法(时间复杂度:O(n)):

思路:

从2开始,依次遍历每一个数,循环变量i通过a[n]可以判断这个数i是不是素数如果a[]是合数
用a[i]依次乘以已经找到的所有素数,得到一些新的合数
如果i是这个素数的倍数停止标记。

比如数字4是合数
当前找到的素数有2,3
对第一个素数2,4*2=8,将8标记为合数,判断4是不是2的倍数,是,结束标记
对第二个素数3,已经结束标记不再进行操作。

#include<bits/stdc++.h>
using namespace std;
int index = 0;
const int n = 1e7;
int a[n+1] = {0};
int b[n+1] = {0};
int main()
{
	for(int i=2;i<=n;i++){
		if(a[i]==0){
			b[index++] = i;
			for(int j=0;(j<index)&&(i*b[j]<=n);j++){
				a[i*b[j]] = 1;
			}
		}else{
			for(int j=0;(j<index)&&(i*b[j]<=n);j++){
				a[i*b[j]] = 1;
				if(i%b[j] == 0){
					break;
				} 
			}
		}
	}
	cout<<index;
	return 0;
}

0.2秒多,厉害! 

注:电脑硬件不同,速度不同,我的速度仅供参考。

 感谢您的观看!

 

 

;