2014-11-13 2 views
1

Добрый день. Существует рекурсивная функция:Пожалуйста, помогите мне с рекурсивной функцией

function f(counter) { 
 
    counter--; 
 
    document.write("<p style='background: blue'>" + counter); 
 
    
 
    if(counter != 0) { 
 
     f(counter); 
 
    } 
 
    
 
    document.write("<p style='background: yellow'>" + counter); 
 
} 
 

 
f(3);

Я не понимаю, как это работает.

В функцию входит счетчик значений 3. Затем счетчик уменьшается, он становится равным 2. Следующий шаг отображается со значением синей секции 2. Тогда условие, что счетчик не является 0 - функцией, рекурсивно вызывает себя. При следующем значении начального счетчика уменьшается и становится равным 1. Затем блок отображается в синей секции. Затем снова запускается условие, потому что даже счетчик не равен 0, функция снова вызывает себя, уменьшая счетчик до 0 и выдает 0 в синей секции. Счетчик следующего шага попадает в условие, в котором завершаются рекурсивные вызовы. Выходы функции 0 в желтой секции. Но тогда мне интересно, почему терминал 1 и 2 в желтой секции?

Я понимаю, почему вывод 2, 1, 0 в синей секции - потому что условие срабатывает, если (counter! = 0), и функция вызывает себя. Если условие счетчика == 0 не запускается, а f (0) завершает вызов - выводы 0 в желтом разделе. Но зачем тогда выполнять предыдущие вызовы функций - 1 и 2 выдает их в желтом разделе, а не в синем, это не я, это понятно.

+2

почему все не-любовь? – jAndy

+1

Продвинутые пользователи иногда забывают, что рекурсия может быть трудной для новичков. –

ответ

1

Это потому, что counter является локальной переменной, ограниченной областью действия f.

// value of counter = 2 
document.write("<p style='background: blue'>" + counter); 

if(counter != 0) { 
    f(counter) // calling f(2), must wait for function to return before continuing. 
} 

// after return, the value of counter is still 2 because it's a local variable 
document.write("<p style='background: yellow'>" + counter); 
4

Рекурсия может быть запутанным, если вы не имели дела с ним, но я попытаюсь объяснить:

Вы звоните: f(3)

Так оно входит и призывает: document.write("<p style='background: blue'>" + counter);

который печатает затем синяя линия с 2 в качестве счетчика 2 после counter--, то он вызывает f(2) (потому что counter != 0, как это 2.)

так называет: document.write("<p style='background: blue'>" + counter);

, который печатает тогда синюю линию с 1 в качестве счетчика 1 после counter--, тогда он называет f(1) (потому что counter != 0 как есть 1.)

Так она называет: document.write("<p style='background: blue'>" + counter);

который печатает затем синюю линию с 0, как счетчик 0 после counter--, то это не вызывает f(0) (потому что counter == 0)

так что теперь мы завершаем функция мы в (где «счетчик == 0»), и она вызывает: document.write("<p style='background: yellow'>" + counter);

, который печатает затем желтую линию с 0, как счетчик равен 0

, то мы вернемся к функции были мы назвали f(0) от и counter == 1 и что вызывает document.write("<p style='background: yellow'>" + counter);

который печатает затем желтая линия с 1, как счетчик 1

тогда мы вернемся к функции были мы назвали f(1) от и counter == 2 и что вызывает document.write("<p style='background: yellow'>" + counter);

который печатает затем желтая линия с 2, а счетчик 2

Я знаю, что это сбивает с толку, но я надеюсь, что это помогает?

* EDIT * Вот мой более подробный и, надеюсь, очень четкое объяснение!

Вот моя попытка:

function f(3) { 
    counter--; 
    document.write("<p style='background: blue'>" + counter); 

    if(counter != 0) { 
     f(counter) // counter equals 2 
    } 

    document.write("<p style='background: yellow'>" + counter); 
} 

Так позволяет просто заменить f(counter) ака f(2) выше с тем, что фактически называется (размещение счетчика ж/Counter2, потому что они являются отдельными переменными:

function f(3) { 
    counter--; 
    document.write("<p style='background: blue'>" + counter); 

    if(counter != 0) { 
      counter2 = counter; 
      counter2--; 
      document.write("<p style='background: blue'>" + counter2); 

      if(counter2 != 0) { 
       f(counter2) // counter2 equals 1 
      } 

      document.write("<p style='background: yellow'>" + counter2); 
     } 
    } 

    document.write("<p style='background: yellow'>" + counter); 
} 

сейчас снова, просто замените f(counter2) aka f(1) выше на то, что на самом деле называется (заменяя counter2 w/counter3, поскольку они снова являются отдельными переменными.)

function f(3) { 
    counter--; 
    document.write("<p style='background: blue'>" + counter); // prints 2 

    if(counter != 0) { 
      counter2 = counter; 
      counter2--; 
      document.write("<p style='background: blue'>" + counter2); // prints 1 

      if(counter2 != 0) { 
       counter3 = counter2; 
       counter3--; 
       document.write("<p style='background: blue'>" + counter3); // prints 0 

       if(counter3 != 0) { // counter3 equals 0 so this is false 
        f(counter3); // this is never called because counter3 DOES equal 0 
       } 

       document.write("<p style='background: yellow'>" + counter3); // prints 0 
      } 

      document.write("<p style='background: yellow'>" + counter2); // prints 1 
     } 
    } 

    document.write("<p style='background: yellow'>" + counter); // prints 2 
} 
+0

Я собирался написать что-то подобное. Это также может помочь, если вы используете инструменты отладки браузера, чтобы установить точку останова в верхней части вашего скрипта и отслеживать ее выполнение. 1) Это поможет вам научиться использовать шаг и перейти к функциям. 2) Он будет показан, как описано выше, точно, что происходит –

+0

@ E.Maggini. Я обновил и добавил гораздо больше деталей. Я думаю, что это будет более полезно, чем трассировка стека. IMO –

+0

@SimplyCraig, большое спасибо за подробное объяснение. Я постараюсь понять. Я не знаю много английского, но обязательно повернись. Еще раз спасибо. – Aleksandr

1

Но почему же тогда завершают предыдущие вызовы функций - 1 и 2 выхода их в желтой секции, а не в синем, это не я, это понятно.

Поскольку после выполнения функции f (3) функция не завершается и ожидает завершения вызова f (2). Когда это будет сделано, он будет идти дальше и записывает 3 в желтый div. И так далее для каждого счетчика.

Imagine f звонит не внутри, а какая-то другая функция myFunc. Он ждет, пока не закончится myFunc. При рекурсии тот же поток.

1

Это, вероятно, происходит потому, что переменная «счетчик» является локальной переменной в функцию f. Вы должны кэшировать переменную, чтобы f запускался, как вы описываете. Отметьте этот ответ здесь: javascript for loop variable and recursion описывает аналогичную проблему и ее решение.

+0

ОК, я прочитаю. Спасибо! – Aleksandr

0

Я понял, что мы рекурсивно называем f (2), f (1), f (0), но мы не заканчиваем вызов, если if (counter! = 0), это условие не будет работать. Дисплей будет 0 желтым. Теперь нам нужно завершить остальные функции f (1) и f (2), эти функции имеют document.write ("<p style = 'background: yellow'>" + counter) ;. Оказывается, когда мы завершаем эти вызовы, выводим 1 и 2 в желтый цвет.

Смежные вопросы