Recursive power function: Why does this work if there's no initial return value?

前端 未结 4 2087
小蘑菇
小蘑菇 2020-12-15 14:27

because power(base, exponent) has no return value unless exponent is 0, initially, shouldn\'t power(base, exponent -1) return \'undefined\', and therefore be unmultipliable,

相关标签:
4条回答
  • 2020-12-15 14:48

    Look at what happens if you try to calculate 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)
    }
    

    ... what is 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)
    }
    

    ... what is 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)
    }
    

    ... what is 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);
    }
    

    ... putting that together, in reverse order as we walk back up the stack...

    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.
    
    0 讨论(0)
  • 2020-12-15 14:53
    function pow(base, exponent) {
        if (exponent === 0) return 1;
        if (exponent > 0) {
            return base * pow(base, exponent - 1)
        } else {
            // handle negative exponent
            return 1 / base * pow(base, exponent + 1)
        }
    }
    
    0 讨论(0)
  • 2020-12-15 14:56

    I think the function makes more sense the other way around, like this:

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

    The return of the if statements are chained together and cannot be resolved until the else statement is executed.

    Examples

    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;
    

    Remember it is the return of the if/else statements that is being passed back up the chain to the function that called it.

    A slightly stupid metaphor

    Let's say you want to ask David a question but you don't want to yell, you could ask there person beside you, who could ask the person beside you, who could ask the person beside you, and so on, until the question was asked to David.

    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
    

    Only once David's answer is known can that piece of information be passed back up the chain of people that asked the question.

    0 讨论(0)
  • 2020-12-15 15:06

    It could be more concise:

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

    Howerver an iterative solution is very much faster:

    function powerNR(base, exp) {
      var result = 1;
      while(exp--) {
        result *= base;
      }
      return result;
    }
    
    0 讨论(0)
提交回复
热议问题