2014-10-05 5 views
0

Так вот от Eloquent Javascript. Я пытаюсь понять, как этот код действительно прошел. Поэтому мы пытаемся найти способ достичь целевого числа, добавив либо 5, либо умножившись на 3, и мы начнем с номера 1. Таким образом, по существу, мы пытаемся найти последовательность таких дополнений и умножений, которые создают цель номер? Например, число 13 может быть достигнуто путем первого умножения на 3, а затем добавления 5 дважды, тогда как число 15 вообще не может быть достигнуто.Рецензия на Javascript из Eloquent Javascript

Вот фрагмент кода:

function findSolution(target) { 
    function find(start, history) { 
    if (start == target) 
     return history; 
    else if (start > target) 
     return null; 
    else 
     return find(start + 5, "(" + history + " + 5)") || 
      find(start * 3, "(" + history + " * 3)"); 
    } 
    return find(1, "1"); 
} 

Результат:

console.log(findSolution(24));// → (((1 * 3) + 5) * 3) 

Видимо, это то, что происходит, когда мы называем findSolution(13):

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

find(1, "1") 
    find(6, "(1 + 5)") 
    find(11, "((1 + 5) + 5)") 
     find(16, "(((1 + 5) + 5) + 5)") 
     too big 
     find(33, "(((1 + 5) + 5) * 3)") 
     too big 
    find(18, "((1 + 5) * 3)") 
     too big 
    find(3, "(1 * 3)") 
    find(8, "((1 * 3) + 5)") 
     find(13, "(((1 * 3) + 5) + 5)") 
     found! 

Вопрос:
1) Я смущен, что происходит, когда мы называем findSolution (13). Как получается, что первая строка находится (1, «1»), когда я не предоставил ей ни стартовый, ни исторический номер? Как код просто переходит к строке:

return find(1,"1") 

Как код копается?
2) Является ли это, как операторы OR работают в рекурсии? В рекурсивной проверке Javascript обычно исследует первую ветвь оператора OR перед тем, как заняться второй ветвью? Является ли эта строка:

find(3, "(1 * 3)") 

проверяется только после того, как все ветви:

find(6, "(1 + 5)") 

не возвращать решение?

+0

См. Также [Более четкое объяснение рекурсии и потока выполнения в JavaScript?] (Http://stackoverflow.com/q/720158/1048572) и [Как эта рекурсия работает?] (Http: // stackoverflow. com/q/15712230/1048572) – Bergi

+0

См. также [Почему эта программа продолжает работать после возврата null?] (http://stackoverflow.com/q/29994249/1048572) – Bergi

ответ

2

1) Если вы посмотрите на код, функция «findSolution» состоит из двух частей: определения метода «find» и вызова этого метода «return find (1,« 1 »)». Само по себе определение не будет производить вычисления, если оно не будет вызвано. Итак, первое выполняемое выражение - «find (1,« 1 »)». Это отправная точка.

2) Операторы OR выполняются в порядке их чтения, поэтому «find (start + 5, ...)» будет сначала выполнен, а затем только если он возвращает null (то есть он не нашел решение) будет выполнено следующее утверждение «find (start * 3, ...)». Из-за рекурсии вы можете получить любое количество выходов «+5» до выполнения «* 3», в зависимости от цели, конечно.

+0

А я вижу, функция определения find (параметр, параметр) ничего не делает, пока он не будет вызван операцией return find (1, "1"). Очень круто. – Jwan622

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