Рекурсивная степенная функция: почему это работает, если нет начального возвращаемого значения? - PullRequest
2 голосов
/ 05 октября 2011

потому что power (base, exponent) не имеет возвращаемого значения, если показатель exponent не равен 0, изначально не должен power (base, exponent -1) возвращать 'undefined', и, следовательно, изначально не должен быть умножаемым?Итак, у меня возникли проблемы следуя логике этого кода.Почему / как это работает?

function power(base, exponent) {
  if (exponent == 0)
    return 1;
  else
    return base * power(base, exponent - 1);
}

Ответы [ 3 ]

8 голосов
/ 05 октября 2011

Посмотрите, что произойдет, если вы попытаетесь вычислить 5^3:

power(5, 3)  ... this should give us 125, let's see if it does...

function power(base, exponent) {    // base = 5, exponent = 3
  if (exponent == 0)                // nope, exponent != 0
    return 1;
  else
    return base * power(base, exponent - 1);  // return 5 * power(5, 2)
}

... что такое power(5, 2)?...

function power(base, exponent) {    // base = 5, exponent = 2
  if (exponent == 0)                // nope, exponent != 0
    return 1;
  else
    return base * power(base, exponent - 1);  // return 5 * power(5, 1)
}

... что такое power(5, 1)?...

function power(base, exponent) {    // base = 5, exponent = 1
  if (exponent == 0)                // nope, exponent != 0
    return 1;
  else
    return base * power(base, exponent - 1);  // return 5 * power(5, 0)
}

... что такое power(5, 0)?...

function power(base, exponent) {    // base = 5, exponent = 0
  if (exponent == 0)                // yup, exponent != 0
    return 1;                       // return 1
  else
    return base * power(base, exponent - 1);
}

... складывая это вместе, в обратном порядке, когда мы возвращаемся в стек ...

power(5, 0) = returns 1
power(5, 1) = 5 * power(5, 0) = 5 * 1 =  returns 5
power(5, 2) = 5 * power(5, 1) = 5 * 5 =  returns 25
power(5, 3) = 5 * power(5, 2) = 5 * 25 =  returns 125

... so, power(5, 3) returns 125, as it should.
5 голосов
/ 05 октября 2011

Это может быть более кратким:

function power(base, exponent) {
  return exponent == 0? 1 : base * power(base, --exponent);
}

Однако итеративное решение намного быстрее:

function powerNR(base, exp) {
  var result = 1;
  while(exp--) {
    result *= base;
  }
  return result;
}
1 голос
/ 16 апреля 2018

Я думаю, что функция имеет больше смысла с другой стороны, например:

const power = (base, exponent) => {
  if (exponent !== 0) {
    return base * power(base, exponent - 1);
  } else {
    return 1;
  }
}

возвращает , если операторы объединены в цепочку и не могут быть разрешены, пока не будет выполнен оператор else .

Примеры

4^0 = else;
4^0 = 1

4^1 = if * else;
4^1 = 4 * 1;

4^2 = if * if * else;
4^2 = 4 * 4 * 1;
    = 4 * 4;
    = 16

// Another way of conceptualising it:

4^2 = if(if(else));
    = 4(4(1));
    = 16;

Помните это возврат из операторов if / else , который передается по цепочке в функцию, которая его вызвала.

Немного глупая метафора

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

const askDavidAQuestion = peopleInBetweenYouAndDavid => {

if (peopleInBetweenYouAndDavid !== 0) {

  console.log('I will ask him');

  return askDavidAQuestion(peopleInBetweenYouAndDavid - 1);

} else {

  console.log('David says no');

}
}

askDavidAQuestion(3);

-> I will ask him
   I will ask him
   I will ask him
   David says no

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...