判断是否为素数
对于一个任意一个正整数,如果它只能被自身或1整除,称其为素数,否则为合数。1比较特殊,既不是质数也不是合数。
基于素数的定义,很快就可以直观的想到代码,对于任意一个正整数,只需要在(1,n)也就是[2,n-1]之间进行遍历,如果n可以被区间中的任何一个数字整除,它就不是质数。否则,如果对整个区间遍历完毕,还未找到一个数字可以整除n,那么这个数字就是质数。
public Test{
//类方法
public static bool isPrime(int n){
for(int i=2;i<=n-1;++i){
if(n%i==0){
return false;
}
}
return true;
}
}
算法时间复杂度分析:对于上边穷举遍历暴力的方法,判断一个正整数是否为素数。所需的时间复杂度是O(n),然而在实际应用中,判断某一个数字是否为为素数只是整个程序当中的一小部分,这样的时间复杂度相对而言还是比较高的。
下面将一种时间复杂度为O(n^(1/2))时间复杂的判断素数的算法。
数学背景:对于任意一个正整数N,可以将其分解为两个因数。特殊情况下N^(1/2)相等,即N=N^(1/2)*N^(1/2)。此外若存在两个因数,则其中一个必然大于N^(1/2),而另外一个必然小于N^(1/2)。因此,只需要在区间[2,N^(1/2)]区间遍历即可,若在此区间存在一个正整数使得N被整除,则其为合数(此时这个因数小于N^(1/2),而另外一个因数必然大于N^(1/2)),否则其为质数。进过这样的 处理可以显著的降低判断是否为质数算法的时间复杂度,达到O(n^(1/2))。
public Test{
public static bool isPrime(int n){
for(int i=2;i<=Math.sqrt(n*1.0);++i){
if(n%i == 0){
return false;
}
}
return true;
}
}
素数筛选法:从小到大遍历每一个数字,将其倍数筛去,剩下的即为素数。
class Test{
private boolean[] p;//用于标记对应下标的数字是否为素数
private int[] prime;
private int len=0;
//构造方法
Test(int n){
p = new boolean[n];
prime = new int[n];
}
public void prime(int n){
for(int i=2;i<n;++i){
if(p[i]==false){
prime[len++] = i;//false表示对应下标为素数
//进行筛选
for(int j=i+i;j<n;j+=i){
p[j] = true;//标记不是素数
}
}
}
}
public void show(int n){
for(int i=0;i<n;++i){
System.out.print(prime[i]+" ");
}
}
}
public class Main{
public static void main(String[] args){
Test t = new Test(100);
t.prime(100);
t.show(100);
}
}
输出100范围内的素数: