2014-01-14 20 views
4

所以,我刚开始探索递归,并且有点卡在一个概念上。这里是一个解决方案,我位于一个数总和函数(f(126)= 1 + 2 + 6 = 9):Javascript递归 - >返回跟踪是什么样的?

function sumDigits(num, sum){ 
if (num === 0) { 
    return sum; 
} else { 
    sum += num % 10; 
    num = Math.floor(num/10); 
    return sumDigits(num, sum); 
}} 

我跟踪下来到基座,到目前为止一切有意义:

**Trace** 
f(126, 0) 
    { 
    sum = 6 
    num = 12 
    f(12, 6) 
    } 
f(12, 6) 
    { 
    sum = 8 
    num = 1 
    f(1, 8) 
    } 
f(1, 8) 
    { 
    sum = 9 
    num = 0 
    f(0, 9) 
    } 
f(0, 9) = 9 

我想对我来说没什么意义的是,基本情况是如何在放卷期间传回的?它究竟是如何旅行?

我期待facepalm,但直到我明白我不认为我可以复制此解决方案。

感谢您的帮助!

+0

什么基地?你是说'总和'? –

+0

你每次发射都会传递数字和总和。 – dandavis

+0

对不起,按'base'我的意思是'base case'(编辑):) –

回答

5

sum在每次调用sumDigits时被累积和传递。只要第一个参数等于0就会返回此值。我发现它有助于明确地写出来的递归:

sumDigits(123, 0); 
    return sumDigits(12, 3); 
     return sumDigits(1, 5) 
      return sumDigits(0, 6) // the base case (sum = 6) 
       return sum; 

最后调用返回6。前一个调用返回最终调用的结果。之前的呼叫在最终呼叫之前返回呼叫(依此类推)。所以他们最终都解开了最后的sum

请注意,每个呼叫都会返回链中下一个呼叫的结果。是什么阻止了基本情况(即导致返回具体值(即无附加呼叫)的条件))。

+0

“只要第一个参数等于0就返回这个值” - >这里存在我的困惑。在返程中,返回sumDigits(0,6)中的sumDigits(1,5)是什么意思?基本情况,对吧?但它是如何旅行的?呃,很困惑。 –

+0

如果'a'返回'b'且'b'返回'c'并且'c'返回'6',则'b'返回'6'并且'a'返回'6'。 –

0

我建议

function sumDigits(num) { 
    if (num < 0) 
     return sumDigits(Math.abs(num)) //handle negative numbers 
    least_sig_digit = num % 10 
    if (num < 10) 
     return least_sig_digit //in case num is a float) 
    else 
     return least_sig_digit + sumDigits(Math.floor(num/10)) 
} 

这样,您将深入到sumDigits返回基本情况,然后泡沫的结果。到达呼叫堆栈顶部时,您应该有所有数字的总和。

这里是如何工作的:

sumDigits(126) 
= 6 + sumDigits(12) 
= (6+2) + sumDigits(1) 
= (6+2+1) 
= 9 

函数调用从顶部到底部的顺序进行。 返回值以自下而上的顺序冒泡,最终返回表达式sumDigits(126)的值9。

想想递归的最好方法是定义从一层移动到下一层的行为,而不用担心大局。只要有人告诉你5! = 5*4!你满意,将递归概念化就容易多了。

什么是sumDigits(126)?这是6 + sumDigits(12)。但是什么是sumDigits(12)?它是(6+2) + sumDigits(1)。等等。

+0

是的,这个解决方案(又名,没有额外的总和参数)更容易让我理解。虽然,经常性sumDigits调用应该采用Math.floor(num/10)参数而不是(num%10),对吗? –

+0

这是正确的。我最初编写了这个函数来将最高有效位数字加到最低有效位数,并忘记更新代码。数字可以任意添加(RTL或LTR)。 – IceArdor

0

它递归地返回sum += num % 10

另一种方式去思考它,它的返回sum但每次调用修改sum(在+=运营商),使得当它到达了底部壳体的sum最内层循环中的值是实际的总和。所以只要通过所有的回报来回报这个价值。

如果你只是想打印你甚至不需要返回任何东西。只要基本情况​​下打印sum的值并返回null。

总结是在基础案例的途中完成的,而不是出路。

+0

请注意,相比之下,IceArdor提供的解决方案在基本案例的出路上进行求和。 – slebetman

+0

对。因此,在我原来的解决方案中,除了传递和数之外,没有任何“工作”正在发生。 –