三种筛选质数的方法
查看原帖
三种筛选质数的方法
1486205
fenghaoran1005楼主2024/10/5 20:24

//求1~n之间所有的质数

//求1~n之间所有的质数

//1.暴力求解,看1~n中每一个数是否为质数 
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
int primes[N],idx; 
bool isprime(int x) //1.暴力求解,看1~n中每一个数是否为质数 时间复杂度:n*sqrt(n) 
{
	if(x < 2) return 0;
	for(int i = 2; i <= x/i; i ++)  //i*i <= x 不用这种写法  sqrt 
	{
		if(x%i == 0) return 0;
	}
	return 1;
}
bool vis[N]; 
void aiprime(int n) //2.素数筛,埃氏筛法  求1~n之间所有的素数 时间复杂度 nloglogn 
{
	for(int i = 2; i <= n; i ++) //用质数去把1~n中比它大的并且是它的倍数的数都标记为合数 
	{
		if(!vis[i]) 
		{
			primes[++idx] = i;
			for(int j = i+i; j <= n; j += i) vis[j] = 1;
		}
	}
} 
void oulaprime(int n) //2.欧拉筛 保证了每一个合数用它的最小质因子去筛掉, 求1~n之间所有的素数 时间复杂度 n 
{
	for(int i = 2; i <= n; i ++)
	{
		if(!vis[i]) 
		{
			primes[idx++] = i;
		}
		for(int j = 0; primes[j] <= n/i; j ++)
		{
			vis[primes[j]*i] = true;
			if(i%primes[j] == 0) break; //保证不被重复筛的关键 
		} 
	}
} 
// 1 2 3 4 5 6 7 8 9 10 11 12  n=12
//prime{2} 标记 4
//prime{2 3}  标记 6  9 
//i=4 prime{2 3}  标记8  【没有用3*4去标记12】 
//i=5 prime{2 3 5}  标记 10 
//i=6 prime{2 3 5} 标记12 
//i=7 prime{2 3 5 7} 标记 14 
//i=8  prime{2 3 5 7} 
//i=9  prime{2 3 5 7}
//i=10  prime{2 3 5 7}  
//i=11  prime{2 3 5 7 11} 
//i=12  prime{2 3 5 7 11} 
int main()
{
	cin >> n;
	/*for(int i = 2;i <= n; i ++) //这是用暴力筛看每一个数是否为质数 
	{
		if(isprime(i)) primes[++idx] = i;
	}*/
	aiprime(n); //这个是调用埃氏筛求1-n中质数的个数,保存在了primes数组中,并且idx表示质数个数 
	cout << idx << endl;
	/*
	oulaprime(n); //这个是调用线性筛求1-n中质数的个数,保存在了primes数组中,并且idx表示质数个数 
	cout << idx << endl;
	*/ 
}
2024/10/5 20:24
加载中...