素数定义: 整数p不等于0,正负1,正负p,且除了正负1,正负p外没有其他约数,那么称整数p为质数或者素数.如果不做特别说明,素数或质数指的是正整数中的质数或者素数.
问题1:判断一个数是否为素数?
朴素的素数判定方法是通过枚举从2-n^0.5 ,看它是否能整除n.时间复杂度为O(n^0.5)
问题2:素数的筛法,列举不大于n的所有素数.
介绍一个简单理解的算法
让每个找出来的素数把他们的倍数排除掉,最小的没有被排除的数就是下一个素数;
具体算法java版:
/*
* 筛法求不大于N的所有素数
* 数组A表示2-N的数
* 对于数组A中不为素数的标记为0
*/
public static void getPrimes(int n){
int[] a=new int[n+1];
for(int i=0;i<=n;i++){
a[i]=i;
}
a[0]=a[1]=0;
for(int i=2;i<=Math.sqrt(n);i++){
if(a[i]!=0){
//踢出当前素数的倍数
for(int j=i*i;j<=n;j+=i){
a[j]=0;
}
}
}
for(int i=2;i<=n;i++){
if(a[i]!=0)System.out.print(a[i]+" ");
}
}
----------------------------------------------
上面的方法在筛选时会对此筛选同一个数,例如2*15与5*6
下面给出一个线性筛法,没有冗余
/*
* 优化:去掉冗余
*/
public static void getPrimers2(int n){
int numPrimer=0;
//素数列表
int[] primer=new int[n];
int[] a=new int[n+1];
//初始化
for(int i=0;i<=n;i++)a[i]=i;
a[0]=a[1]=0;
for(int i=2;i<=n;i++){
//是素数添加到列表
if(a[i]!=0){
primer[numPrimer++]=i;
}
/*
* 对于i是合数,合数*素数肯定是合数
* 对于i是素数,只筛出 不大于i的质数*i
*/
for(int j=0;j<numPrimer;j++){
//超过最大数,退出循环
if(i*primer[j]>n)break;
a[i*primer[j]]=0;
//只筛出 不大于i的质数*i
if(i%primer[j]==0)break;
}
}
for(int i=0;i<numPrimer;i++){
System.out.print(primer[i]+" ");
}
}