PHP рекурсивный факторинг ошибок
Поэтому я новичок в идее рекурсии, и я написал этот простой код, чтобы вычислить число ($n), это код:
$n = 120;
$y = 1;
function factor($n, $y) {
if($y > $n) {
return 1;
} else {
$x = $n / $y;
list($whole, $dec) = array_pad(explode('.', $x), 2, Null);
if($dec == '') {
echo 'x:' . $x . ' y:' . $y . '</br>';
return factor($n, ($y + 1));
}
}
}
это то, что код выводит:
x:120 y:1
x:60 y:2
x:40 y:3
x:30 y:4
x:24 y:5
x:20 y:6
поэтому мой вопрос: почему это останавливается до того, как завершится?
3 ответа
Решение
Ваш следующий шаг будет 120 / 7, что равно 17.142857....
Так что эта проверка не проходит и рекурсия как таковая не происходит:
if($dec=='') // $dec would equal to 142857.....
{
echo'x:'.$x.' y:'.$y.'</br>';
return factor($n,($y+1));
}
else
{
$x=$n/$y;
list($whole,$dec)=array_pad(explode('.', number_format($x)), 2, Null);
if($dec=='')
{
echo'x:'.$x.' y:'.$y.'</br>';
return factor($n,($y+1));
}
}
ЧАСТЬ ДЕСЯТИЧНОГО ОГРАНИЧЕНИЯ
Есть две вещи, которые я вижу неправильно в вашем примере:
- Ваша рекурсия останавливается при первом обнаружении дробного значения. Хвостовая рекурсия (
return factor($n, $y + 1);
) происходит только когда$dec == ''
, В противном случае функция просто завершается. Вот почему это останавливается, когда$y
это 7. - Ваше условие для завершения рекурсии (
$y > $n
) это неверно. Вы хотите прервать рекурсию, когда делитель больше, чем частное, т.е. когда$y > $x
- потому что это означает, что вы нашли все целочисленные факторы.
Я думаю, что это то, что вы хотите:
$n = 120;
$y = 1;
function factor($n, $y) {
$x = $n / $y;
if($y > $x) {
return 1;
} else {
list($whole, $dec) = array_pad(explode('.', $x), 2, Null);
if($dec == '') {
echo 'x:' . $x . ' y:' . $y . "</br>\n";
}
return factor($n, ($y + 1));
}
}
echo factor($n, $y);