今天做搜索的题的时候遇到了一个素数的问题,所以整理一下
1.最普通的方法不做赘述----按照素数的定义 时间复杂度O(n*n)
public class 普通的方法 {
static final int max=100;
static int prime[]=new int[max];
public static void main(String[] args) {
int k=0;
for(int i=2;i<max;i++){
boolean flag=true;
for(int j=2;j<=Math.sqrt(i);j++)
if(i%j==0)
flag=false;
if(flag) prime[k++]=i;
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
2.埃拉特斯特尼筛法--当i为素数,i的倍数i*k都不是素数 时间复杂度O(nloglogn)
import java.util.Arrays;
public class 埃拉特斯特尼筛法 {
static final int max=100;
static boolean is_prime[]=new boolean[max];
static int prime[]=new int[max];
public static void main(String[] args) {
Arrays.fill(is_prime, true);
is_prime[0]=is_prime[1]=false;
int k=0;
for(int i=2;i<max;i++){
if(is_prime[i]){
prime[k++]=i;
for(int j=2*i;j<max;j+=i){
is_prime[j]=false;
}
}
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
3.线性欧拉筛法--每个合数只被它的最小素因子筛选一次 时间复杂度O(n)\
import java.util.Arrays;
public class 线性欧拉筛法 {
static final int max=100000;
static boolean vis[]=new boolean[max];
static int prime[]=new int[max];
public static void main(String[] args) {
Arrays.fill(vis, true);
vis[0]=vis[1]=false;
int k=0;
for(int i=2;i<max;i++){
if(vis[i])
prime[k++]=i;
for(int j=0;j<k&&i*prime[j]<max;j++){
vis[i*prime[j]]=false;
if(i%prime[j]==0){
break;
}
}
}
for(int i=0;i<k;i++){
System.out.println(prime[i]);
}
}
}
vis[i*prime[j]]=false 把prime里记录的素数升序来当作消去合数的最小素因子
if(i%prime[j]==0) break;
当i是prime[j]的倍数时,i=k*prime[j],如果继续进行j+1,i*prime[j+1]=prime[j]*(k*prime[j+1]),
prime[j]是最小素因子,当i=k*prime[j+1]时,会重复,所以break
eg:当i=8,j=0,prime[0]=2,如果不break,i*prime[j+1]=8*3=12*2,也就是说在i=12的时候也会筛这个合数