完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
如果一个数恰好等于它的真因子之和,则称该数为“完全数”。第一个完全数是6,第二个完全数是28,第三个完全数是496,后面的完全数还有8128、33550336等等。
以上解释来自百度百科。
根据这个解释,需要了解质因数分解。质因数分解概念:因数是指整数a除以整数b(b≠0) 的商正好是整数而没有余数,我们就说b是a的因数。因此,分解质因数可以通过以下实现(此方法在本次算法中未使用,只是实现因数分解):
/**
* @param $n
* 分解质因数
* 因数是指整数a除以整数b(b≠0) 的商正好是整数而没有余数,我们就说b是a的因数。
*/
private function splitePrime($n)
{
$arrPrime = array();
for($i = 1; $i <= $n; $i++){
if($n % $i == 0){
$arrPrime[] = $i;
}
}
return $arrPrime;
}
根据这个分解方法,我们可以改写成完数算法的真因子,如下:
/**
* 判断是否是完数
* @param $n
* @return bool
* 一个数如果恰好等于除它本身外的因子之和,这个数就称为"完数",也叫“完美数”。例如6=1+2+3.(6的因子是1,2,3)
*/
private function getPerfectPrimeSum($n)
{
$sum = 0;
//循环,不包括自身
for($i = 1; $i < $n; $i++){
if($n % $i == 0){
$sum += $i;
}
}
if($sum == $n){
return true;
}
return false;
}
功能实现
/**
* @name 完美数\完数
* @param $max
* 一个数如果恰好等于除它本身外的因子之和,这个数就称为"完数",也叫“完美数”。例如6=1+2+3.(6的因子是1,2,3)
*/
public function perfectNum($max)
{
$arr = array();
for($i = 1; $i <= $max; $i++){
//echo $i.'--';
if($this->getPerfectPrimeSum($i)){
$arr[] = $i;
}
}
return $arr;
}
运行结果(目前我只跑到1万以内的数,再大的需要优化算法了)
调用:
$data = $this->perfectNum(10000);
print_r($data);
die();
返回:
Array
(
[0] => 6
[1] => 28
[2] => 496
[3] => 8128
)