因此,我刚刚解决了AlgoExpert上的一个代码挑战,我试图更深入地理解为什么我的代码工作,所以我使用PythonTutor来可视化代码的执行,我很想知道为什么每次进行递归调用时,arraySum重新初始化为0,但不知怎么地保留了以前由数组中的元素之和组成的值。
这是我解决的问题

这是我的代码:
function productSum(array, multiplier=1) {
let arraySum = 0;
array.forEach(el => Array.isArray(el) ? arraySum+=productSum(el, multiplier+1) : arraySum += el)
return arraySum * multiplier
}
productSum([5, 2, [7, -1], 3, [6, [-13, 8], 4]])下面是PythonTutor中可视化的链接
发布于 2021-07-31 16:57:39
您的算法包含递归调用:您的productSum有时会使用不同的参数,在数据结构的更深层次上再次调用自己。
每个呼叫都有自己的呼叫框架,并具有自己独特的范围。您的let arraySum = 0是在函数(作用域)中定义的,因此除了其他调用之外,每个调用都有自己的arraySum (初始化为0)。
我做了另一个图表,每个盒子/椭圆形都是一个调用框架:

没有显示乘法部分。
每个调用帧都有自己的作用域和自己的array/multiplier/arraySum变量。每个调用都以arraySum = 0开头,使用.forEach向该变量添加,然后返回存储在变量中的值。这就是为什么在Python可视化器中,您有时会看到arraySum变为0。并不是某个实际的arraySum变成了0,而是因为您正在查看一个全新的函数调用,就在let arraySum = 0语句之后。
在一个作用域中更改arraySum对另一个作用域的arraySum没有影响,即使这两个作用域用于相同的函数(但不同的函数调用!)。
发布于 2021-07-31 16:44:51
当您意识到productSum的每一次执行都有自己的arraySum变量时,就很明显了。尽管名称每次都是相同的,但它实际上是一个与其他变量无关的变量(在递归树中),这些变量恰好具有相同的名称。
每次进行递归调用时,调用方的productSum都会在堆栈帧上结束,在递归调用返回时从那里还原,然后将返回的值添加到自己的productSum中。
因此,当从递归中回溯时,一个值正在累积,所有这些不同的productSum变量在传递一个中间结果时都起到了一定的作用,直到它被返回给调用者,调用方进一步积累了它,...etc。
https://stackoverflow.com/questions/68603979
复制相似问题