Ehrlich screening and Euclidean screening and rapid determination of other prime numbers
1. Ehrlich screening;
Time complexity: O(nloglogn);
Idea: To find all prime numbers from 1 to n, first assume that 1 to n are prime numbers, then
1) 0 is not a prime number, 1 is not a prime number, mark 0, 1 is a non-prime number;
2) Starting from 2, as long as it is a prime number, the multiples of the prime number are marked as non-prime numbers;
Code:
#include<stdio.h>
#include<stdlib.h>
int prime[100000];
int is_prime[100000];
int sieve(int n)
{
for(int i=0;i<=n;i++){
is_prime[i]=1;
}//先初始化is_prime数组均为1,表示0-n仅是素数
is_prime[0]=0;//0不是素数
is_prime[1]=0;//1不是素数
int len=0;
for(int i=2;i<=n;i++){
if(is_prime[i]==1){
//如果是素数,将其所有倍数标记为不是素数
prime[len++]=i;
for(int j=2*i;j<=n;j+=i){
is_prime[j]=0;
}
}
}
return len;//返回该区间所有素数
}
int main()
{
int n;
scanf("%d",&n);
int len=sieve(n);
for(int i=0;i<len;i++){
printf("%d",prime[i]);
if(i<len-1)printf(" ");
}
return 0;
}
2. Euclidean screening
For non-prime positive integers, (except 1), they can always be split into products of prime numbers. In the process of sifting from 1 to this number, the number may be sifted out many times, so it is often better to use European sieve fast.
Code:
#include<stdio.h>
int flag[100001];//标记是否已经被筛出
int prime[10000];//存放素数的数组
int sieve(int n)
{
int len=0;
for(int i=0;i<=n;i++){
flag[i]=0;//flag为0说明未被筛出;为1说明已经被筛出;
}
flag[0]=flag[1]=1;//0,1不是素数,直接筛出去;
for(int i=2;i<=n;i++){
if(flag[i]==0){
//如果当前最前面的未被筛出说明是素数,入表。
prime[len++]=i;
}
for(int j=0;prime[j]*i<=n;j++){
flag[prime[j]*i]=1;//标记为非素数
if(i%prime[j]==0)break;//仔细想明白此处为何是i%prime[j]==0就break!
}
}
return len;
}
int main()
{
int n;
scanf("%d",&n);
int len=sieve(n);
for(int i=0;i<len;i++){
printf("%d",prime[i]);
if(i<len-1)printf(" ");
}
return 0;
}
3. Quick determination of whether a single number is a prime number
Code:
int isPrime(unsigned long long int num)//速度是普通的素数判定的6倍
{
if(num==1)return 0;//1不是素数
if(num==2||num==3)return 1;//2,3是素数单独讨论
if(num%6!=5&&num%6!=1)return 0;//其余所有素数对6取余结果一定为1或5,不满足就不是素数
for(int i=2;i<sqrt(num);i+=6){
//次数i+=6,比普通的要快很多
if(num%i==0||num%(i+2)==0)return 0;
}
return 1;
}