使用while循环计算末尾为9的前5000个质数的问题求助
问题分析与修正提示
你的代码存在多个逻辑和语法问题,导致无法正常运行,以下是具体问题和修正方案:
主要问题点
- 函数重复定义:在
while循环内部定义findPrime函数,每次循环都会尝试重新定义该函数,PHP不允许重复定义同名函数,会直接抛出错误。必须把函数定义移到循环外部。 - 质数判断逻辑错误:
findPrime函数不管输入的数是不是质数,都会返回$x。正确逻辑是:遍历因数时找到能整除的数,直接返回false(说明不是质数);遍历结束没找到因数,才返回true。另外,判断质数的循环上限不需要到$x/2,到sqrt($x)就足够,能大幅提升效率。 - 错误的数组操作:
end($array[$j])是错误用法,str_split($primeList[$j])得到的是当前数字的各位数组,直接用end($array)就能获取最后一位,不需要加[$j]。 - 提前终止程序:循环中使用
return会直接终止整个脚本,导致无法继续收集后续符合条件的质数,必须移除这个return语句。 - 无效的质数收集:你把所有
$x都加入$primeList,但实际上应该先判断$x是质数,再判断末尾是否为9,没必要维护一个全量质数列表。 - 循环条件错误:
count($div9) <= 5000会导致收集到5001个元素才停止,应该改为count($div9) < 5000。
修正后的代码
<?php $div9 = []; $x = 2; // 质数判断函数移到循环外 function isPrime($num) { if ($num <= 1) { return false; } // 优化循环上限到平方根,减少遍历次数 $sqrtNum = sqrt($num); for ($i = 2; $i <= $sqrtNum; $i++) { if ($num % $i === 0) { return false; } } return true; } while (count($div9) < 5000) { if (isPrime($x)) { // 用取模判断末尾是否为9,比转数组高效得多 if ($x % 10 === 9) { $div9[] = $x; } } $x++; } // 可取消注释查看结果 // print_r($div9); ?>
额外优化提示
- 除了2以外,所有偶数都不是质数,可以直接跳过偶数,从3开始每次加2,进一步提升效率:
// 单独处理2(末尾不是9,无需加入结果) $x = 3; while (count($div9) < 5000) { if (isPrime($x)) { if ($x % 10 === 9) { $div9[] = $x; } } $x += 2; }
内容的提问来源于stack exchange,提问作者student
相关产品推荐
相关产品推荐

