Как я могу сделать эту функцию хвостовой рекурсивной?

Мне интересно, если мой алгоритм хвостовой рекурсии; Я только что сделал эту функцию для красивой печати массива в PHP:

function get_pretty_output($value, $first=true, $indent = ''){
    if (!is_array($value)) { return $value.PHP_EOL; }
    if (empty($value)) { if ($first) { return 'Array()'.PHP_EOL; } else { return preg_replace('/    /', '', $indent, 1).')'.PHP_EOL; }}
    if ($first) {
            $output = 'Array'.PHP_EOL.$indent.'('.PHP_EOL;
            $indent .='    ';
            $first = false;
    } else {
        $output = '';
    }
    reset($value);
    $key = key($value);
    return $output .= $indent . 
        '[' . 
        $key . 
        '] => ' . 
        get_pretty_output(array_shift($value), true, $indent) . 
        get_pretty_output($value, $first, $indent);
}

потому что ни

$pretty_string = print_r($array, true);

ни

ob_start(); 
var_dump($array); 
$pretty_string = ob_get_contents(); 
ob_end_clean();

кажется, работает, когда клиент отключается даже с ignore_user_abort(true) (PHP 5.6).

Я даже не знаю, получает ли PHP выгоду от хвостовой рекурсии (мне сказали, что это не так), но в любом случае я хотел бы знать, будет ли это верным примером. Я так не думаю (нужно сохранить контекст функции для использования во втором вызове), но я не могу найти эквивалентный алгоритм хвостовой рекурсии. Есть ли способ, которым я могу следовать?

1 ответ

Решение

Это не будет примером хвостовой рекурсии, потому что вычисления все еще выполняются в более ранних рекурсивных вызовах ПОСЛЕ возврата значения. Рассмотрим пример, приведенный в предыдущем посте Stackru ( Что такое хвостовая рекурсия?). В этом случае оператор ".=" Завершит объединение, и ТО вернет результат в функцию.

Чтобы сделать этот хвост рекурсивным, вы должны изменить свой код, напечатав переменную output перед выполнением рекурсивного вызова.

Другие вопросы по тегам