Что в терминах неспециалиста является Рекурсивной функцией с помощью PHP

Кто-либо может объяснить рекурсивную функцию мне в PHP (не используя Fibonacci) на языке неспециалиста и с помощью примеров? я смотрел на пример, но Fibonacci полностью потерял меня!

Заранее спасибо ;-) Также, как часто Вы используете их в веб-разработке?

72
задан James Westgate 3 August 2018 в 08:34
поделиться

7 ответов

Термины Laymens:

Рекурсивная функция - это функция, которая сама вызывает

Немного подробнее:

Если функция продолжает вызывать саму себя, как она узнает, когда остановиться? Вы устанавливаете условие, известное как базовый вариант. Базовые случаи сообщают нашему рекурсивному вызову, когда следует остановиться, в противном случае он будет зацикливаться бесконечно.

Хорошим обучающим примером для меня, так как у меня сильная математическая подготовка, был факториал . Судя по комментариям ниже, кажется, что факториальной функции может быть слишком много, я оставлю ее здесь на всякий случай, если вы этого захотите.

function fact($n) {
  if ($n === 0) { // our base case
     return 1;
  }
  else {
     return $n * fact($n-1); // <--calling itself.
  }
}

Что касается использования рекурсивных функций в веб-разработке, я лично не прибегаю к использованию рекурсивных вызовов. Не то чтобы я считал плохой практикой полагаться на рекурсию, но они не должны быть вашим первым вариантом. При неправильном использовании они могут быть смертельными.

Хотя я не могу конкурировать с примером каталога, я надеюсь, что это немного поможет.

(20.04.10) Обновление:

Было бы также полезно проверить этот вопрос, где принятый ответ демонстрирует в терминах непрофессионала, как работает рекурсивная функция. Несмотря на то, что вопрос OP касался Java, концепция та же,

88
ответ дан 24 November 2019 в 12:34
поделиться

Это функция, которая вызывает сама себя. Это полезно для прохождения определенных повторяющихся структур данных, таких как деревья. HTML DOM - классический пример.

Пример древовидной структуры в javascript и рекурсивной функции для «обхода» дерева.

    1
   / \
  2   3
     / \
    4   5

-

var tree = {
  id: 1,
  left: {
    id: 2,
    left: null,
    right: null
  },
  right: {
    id: 3,
    left: {
      id: 4,
      left: null,
      right: null
    },
    right: {
      id: 5,
      left: null,
      right: null
    }
  }
};

Чтобы пройтись по дереву, мы многократно вызываем одну и ту же функцию, передавая дочерние узлы текущего узла той же функции. Затем мы снова вызываем функцию, сначала в левом узле, а затем в правом.

В этом примере мы получим максимальную глубину дерева

var depth = 0;

function walkTree(node, i) {

  //Increment our depth counter and check
  i++;
  if (i > depth) depth = i;

  //call this function again for each of the branch nodes (recursion!)
  if (node.left != null) walkTree(node.left, i);
  if (node.right != null) walkTree(node.right, i);

  //Decrement our depth counter before going back up the call stack
  i--;
}

Наконец, мы вызываем функцию

alert('Tree depth:' + walkTree(tree, 0));

Отличный способ понять рекурсию - это пошаговое выполнение кода во время выполнения.

9
ответ дан 24 November 2019 в 12:34
поделиться

Рекурсия - это причудливый способ сказать: «Сделайте это еще раз, пока оно не будет выполнено».

Две важные вещи:

  1. Базовый вариант - у вас есть цель, которую нужно достичь.
  2. Тест - как узнать, добрались ли вы до того места, куда собираетесь.

Представьте себе простую задачу: отсортировать стопку книг по алфавиту. Простой процесс - взять первые две книги и отсортировать их. А теперь переходим к рекурсивной части: есть ли еще книги? Если да, сделайте это снова. «Сделай это снова» - это рекурсия. «Есть ли еще книги?» - это проверка. И «нет, больше нет книг» - это базовый вариант.

4
ответ дан 24 November 2019 в 12:34
поделиться

В основном это. Он продолжает вызывать себя до тех пор, пока не будет выполнен

void print_folder(string root)
{
    Console.WriteLine(root);
    foreach(var folder in Directory.GetDirectories(root))
    {
        print_folder(folder);
    }
}

Также работает с циклами!

void pretend_loop(int c)
{
    if(c==0) return;
    print "hi";
    pretend_loop(c-);
}

Вы также можете попробовать погуглить. Обратите внимание на «Возможно, вы имели в виду» (щелкните по нему ...). http://www.google.com/search?q=recursion&spell=1

1
ответ дан 24 November 2019 в 12:34
поделиться

Примером может быть печать каждого файла в любых подкаталогах данного каталога (если у вас нет символических ссылок внутри этих каталогов, которые могут каким-то образом нарушить работу). Псевдокод печати всех файлов выглядит так:

function printAllFiles($dir) {
    foreach (getAllDirectories($dir) as $f) {
        printAllFiles($f); // here is the recursive call
    }
    foreach (getAllFiles($dir) as $f) {
        echo $f;
    }
}

Идея состоит в том, чтобы сначала распечатать все подкаталоги, а затем файлы текущего каталога. Эта идея применяется ко всем подкаталогам, и это причина для рекурсивного вызова этой функции для всех подкаталогов.

Если вы хотите попробовать этот пример, вам нужно проверить специальные каталоги . и .. , иначе вы застрянете в постоянном вызове printAllFiles (".") . Кроме того, вы должны проверить, что печатать и какой у вас текущий рабочий каталог (см. opendir () , getcwd () , ...).

31
ответ дан 24 November 2019 в 12:34
поделиться

Рекурсия - это альтернатива циклам, они редко добавляют больше ясности или элегантности в ваш код. Хороший пример был дан в ответе Прогмана: если бы он не использовал рекурсию, он был бы вынужден отслеживать, в каком каталоге он находится в настоящее время (это называется состоянием). Рекурсии позволяют ему вести учет с использованием стека (область, в которой переменные и возвращаемый адрес метода сохраняются)

Стандартные примеры факториала и Фибоначчи бесполезны для понимания концепции, потому что их легко заменить циклом.

1
ответ дан 24 November 2019 в 12:34
поделиться

Проще говоря: рекурсивная функция - это функция, которая вызывает сама себя.

7
ответ дан 24 November 2019 в 12:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: