求解素数(质数)集合的3种常用算法整理(Java)
质数定义:只能被1或者自身整除的自然数(不包括1),称为质数。
方法一:根据质数的定义求(效率最低)
利用它的定义可以循环判断该数除以比它小的每个自然数(大于1),如果有能被它整除的,则它就不是质数。
时间复杂度:O(n^2)
private static boolean isPrime1(int numSum){
boolean flag=true;
for (int j=numSum-1;j>1;j--){
if (numSum%j==0){
flag = false;
}
}
return flag;
}
方法二:利用合数定理(原理和方法一一致,效率提高了)
如果一个数是合数,那么它的最小质因数肯定小于等于他的平方根。
例如,20的最小质因数4必然小于20开方。
时间复杂度:O(n^1/2)
private static boolean isPrime2(int num){
int s = (int) Math.sqrt(num);
boolean flag = true;
for (int j=2;j<=s;j++){
if (num % j == 0){
flag = false;
}
}
return flag;
}
方法三:筛法求质数(效率最高,但会比较浪费内存)
首先建立一个boolean类型的数组,用来存储你要判断某个范围内自然数中的质数.
例:
你要输出小于100的质数,可以建立一个大小为101(建立11个存储位置是为了让数组位置与其大小相同)的
boolean数组,位置1置false,其他位置初始化为true。
即数组初始状态 [null,false,true,true......]
然后再获取数字n的开方,即10,然后再从2开始,2的倍数位置置false,即 4 6 8 10....,
3的倍数位置置false即 6 9 12..........,以此类推,就把初始数列的合数位置值变成false,true值的位置则为素数。
private static boolean [] isPrime3(int num){
boolean [] array = new boolean[num+1];
array[1] = false;
for (int i = 2;i < num;i++){
array[i] = true;
}
int s = (int)Math.sqrt(num);
for (int i = 2;i<=s;i++){
if (array[i]){
for (int j=i;j*i<=num;j++){
array[j*i] = false;
}
}
}
return array;
}