获取某个数之间的质数。
概念:大于1自然数,且只能被它和1整除称为质数。
问题:求两个数之间的质数,可以去掉偶数(2特殊判定),然后依次遍历两个数之间的数。
方式:使用该数依次除以2至它的一半的数,若能找到某次整除,该数可立即判定为非质数。例如:求100-200之间的质数,因为100是大于2的偶数,直接跳过,从101开始除以2~50若能找到某个数整除数,该数是质数。
说明:若求高效方式参见第二种即可。
// num是否是质数
// 方式一:直接计算2~num之间(不包含2),num是否能被整除,若有一个能整除,则非质数直接返回。
// 这种比较耗时,时间复杂度是O(n)
function isPrimeNumber1($num){
// 2特殊判定
if ($num == 2) {
return true;
}
// 偶数直接返回
if ($num % 2 == 0) {
return false;
}
// 其他奇数需要除法计算
for($i=2; $i< $num; $i++){
if($num % $i == 0){
return false;
}
}
return true;
}
// 方式二:使用其实位置法,每次遍历可以减小结束位置,大于该值的更本不需要再判定,可以加速判定。
// 设定一个起始结束位置,初始位置为2,结束位置为num,每次计算后重新计算结束位置end
// 计算方式是end = num / i
// 这种耗时少,时间复杂度是O(log n)
function isPrimeNumber2($num){
// 2特殊判定
if ($num == 2) {
return true;
}
// 偶数直接返回
if ($num % 2 == 0) {
return false;
}
// 其他奇数需要除法计算,start在变大,那end数需要变小
$start = 2;
$end = $num;
for($i=$start; $i < $end; $i++){
if($num % $i == 0){
return false;
}
$end = ceil($num / $i);
}
return true;
}
// 测试
function getRangePrimeNumber($a, $b){
$tmp = [];
if ($a < 2) {
return $tmp;
}
if ($a > $b) {
return $tmp;
}
if ($a == 2) {
$tmp[] = 2;
$a += 1;
}
for($i=$a; $i < $b; $i++){
if(isPrimeNumber1($i)){
$tmp[] = $i;
}
}
return $tmp;
}
// 调用运行
$temp = getRangePrimeNumber(101,200);
print_r(join(',', $temp));
// 结果
// 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199