Правильная ли рекурсивная функция?

12
-
На сайте с 07.12.2005
Offline
97
-K-
897

Насколько правильна с точки зрения рекурсии данная функция?


function stripsl($str)
{
if (is_array($str))
{
foreach ($str as &$one)
{
$one = stripsl($one);
}
return $str;
}
else
{
return stripslashes($str);
}
}
to4kaRU
На сайте с 01.09.2005
Offline
14
#1

Вроде, все ок.

В 4-ке только работать не будет.

-
На сайте с 07.12.2005
Offline
97
-K-
#2

Код рабочий 100%. Имелось ввиду работоспособность с точки зрения алгоритма.

Сам спросил, сам ответил :)

http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F#.D0.A0.D0.B5.D0.BA.D1.83.D1.80.D1.81.D0.B8.D1.8F_.D0.B2_.D0.BF.D1.80.D0.BE.D0.B3.D1.80.D0.B0.D0.BC.D0.BC.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B8

Имеем дело с хвостовой рекурсией, поэтому для оптимизации интерпретатором правильнее так:


function stripsl($str)
{
if (is_array($str) || is_object($str))
{
foreach ($str as &$one)
{
$one = stripsl($one);
}
}
else
{
$str = stripslashes($str);
}

return $str;
}
Kolyaj
На сайте с 28.03.2006
Offline
69
#3

А еще лучше так:


function stripsl($str) {
return is_array($str) ? array_map("stripsl", $str) : stripslashes($str);
}
-
На сайте с 07.12.2005
Offline
97
-K-
#4

По моему нет.

Это упрощенный вариант вида


function stripsl($str) {
if (is_array($str))
return array_map("stripsl", $str);
else
return stripslashes($str);
}

А это уже получается 2 точки возврата из функции. При наличии 1, функция будет оптимизирвана интерпретатором.

Kolyaj
На сайте с 28.03.2006
Offline
69
#5

Нет, не правильно вы рассуждаете. Это в вашем случае 2 точки возврата, в моем одна. Более того, без использования циклов и присваиваний (конечно array_map делает цикл, но на более низком уровне). Вообще говоря конструкция ?: эффективней if-else.

mustafa
На сайте с 28.10.2005
Offline
202
#6

Kolyaj правильно все сказал. И его функция будет работать быстрее.

mustafa
На сайте с 28.10.2005
Offline
202
#7
Kolyaj:
Нет, не правильно вы рассуждаете. Это в вашем случае 2 точки возврата, в моем одна.

это как? :) тоже две. Визуально одна - фактически две.

-K-:
А это уже получается 2 точки возврата из функции. При наличии 1, функция будет оптимизирвана интерпретатором.
оптимизирована в плохую сторону. Расчет алгоритма думаю приводить не надо? :)
-
На сайте с 07.12.2005
Offline
97
-K-
#8
mustafa:
оптимизирована в плохую сторону. Расчет алгоритма думаю приводить не надо? :)

Почему в плохую сторону? Можно поподробнее, пожалуйста.

mustafa
На сайте с 28.10.2005
Offline
202
#9
-K-:
Почему в плохую сторону? Можно поподробнее, пожалуйста.

потому что у Kolyaj функция stripsl() всегда заканчивает свою работу, при вызове самой себя. А у вас нет. И когда дойдем до конца рекурсии и начнем возвращать результаты у вас будет происходить сначала выход из цикла foreach и if и далее return $str. А над $str мы никаких действий не производим и делаем return того, что получили в фактическом параметре функции. Это алгоритмическая ошибка.

Дебаггера нету - там бы все четко было видно при трейсинге.

Kolyaj
На сайте с 28.03.2006
Offline
69
#10
mustafa:
это как? тоже две. Визуально одна - фактически две.

и визуально и фактически одна. Так как сначала вычисляется выражение ?:, потом возвращается значение этого выражения.

Для наглядности можно так:


function stripsl($str) {
$temp = is_array($str) ? array_map("stripsl", $str) : stripslashes($str);
return $temp;
}

что то же самое, но с использованием промежуточной переменной.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий