1、基础方法
private boolean isPrime1(int n){
if(n < 2) return false;
for(int i = 2; i <= Math.sqrt(n); i++){
if(n % i == 0) return false;
}
return true;
}
- 这是
isPrime1
方法,它接受一个整数n
作为输入,并返回一个布尔值,指示n
是否为质数。 - 第一行检查
n
是否小于2。如果是,方法立即返回false
,因为质数的定义是大于1的数。 for
循环从i = 2
开始,迭代直到i
小于等于n
的平方根。- 在循环内部,它检查
n
是否能被i
整除(即n % i == 0
)。如果是,方法返回false
,因为n
不是质数。 - 如果循环完成而没有找到
n
的任何因子,方法返回true
,表示n
是质数。
2、加强版本
private boolean isPrime2(int n){
if(n == 2 || n == 3) return true;
if(n % 6 != 1 && n % 6 != 5) return false;
for(int i = 5; i <= Math.sqrt(n); i += 6){
if(n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}
- 这是
isPrime2
方法,也接受一个整数n
作为输入,并返回一个布尔值,指示n
是否为质数。 - 前两行检查
n
是否等于2或3。如果是,方法立即返回true
,因为2和3是质数。 - 下一行检查
n
除以6的余数是否不等于1且不等于5。如果是,方法返回false
,因为不满足模6余数为1或5的数不是质数。 for
循环从i = 5
开始,迭代直到i
小于等于n
的平方根。- 在循环内部,它检查
n
是否能被i
或i + 2
整除(即n % i == 0
或n % (i + 2) == 0
)。如果是,方法返回false
,因为n
不是质数。 - 如果循环完成而没有找到
n
的任何因子,方法返回true
,表示n
是质数。
这两个算法用于判断一个数是否为质数,它们的实现方式略有不同,但时间和空间复杂度相似。第二个算法isPrime2
包含一些优化,以跳过不必要的迭代,可能在某些情况下稍微更高效。
3、艾斯拉尼斯素数筛法
/**
* 艾斯拉尼斯素数筛法
* @param n 求 1 ~ n 之间的素数
* @param isPrime 标记是否为素数
*/
private void isPrime3(int n, boolean[] isPrime){
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for(int i = 2; i <= n; i++){
if(isPrime[i]){
for(int j = i * i; j <= n; j += i){
isPrime[j] = false;
}
}
}
}
- 这是一个使用艾斯拉尼斯素数筛法的方法,用于求解1到n之间的素数。
- 方法的参数包括一个整数n,表示要求解的范围,以及一个布尔类型的数组isPrime,用于标记是否为素数。
Arrays.fill(isPrime, true)
将isPrime数组中的所有元素初始化为true,表示初始时都被标记为素数。isPrime[0] = isPrime[1] = false
将isPrime数组中的索引0和1的元素标记为false,因为0和1不是素数。for
循环从2开始迭代到n,对于每个i,执行以下操作:
- 如果isPrime[i]为true,表示i是素数,进入内部的嵌套循环。
- 内部的嵌套循环从i的平方开始,每次递增i,直到j小于等于n,对于每个j,将isPrime[j]标记为false,表示j不是素数。
- 方法执行完毕后,isPrime数组中的元素标记为true的索引即为素数。
这个算法使用了艾斯拉尼斯素数筛法,通过不断排除合数的方式来筛选出素数。它的时间复杂度为O(nloglogn),相对于其他常规的素数判断算法,它在求解大范围内的素数时具有较高的效率。