Javascript 堆栈和递归函数
我希望这不是一个重复的问题——尽管我在这方面找不到太多帮助 我正在练习递归函数(我是一个新手),我正在尝试将数组中的每个数字相乘。有点像阶乘。我有这个代码,但结果它只返回Javascript 堆栈和递归函数,javascript,arrays,recursion,Javascript,Arrays,Recursion,我希望这不是一个重复的问题——尽管我在这方面找不到太多帮助 我正在练习递归函数(我是一个新手),我正在尝试将数组中的每个数字相乘。有点像阶乘。我有这个代码,但结果它只返回未定义的 代码如下: var stack = []; function countDown(int) { stack.push(int); if (int === 1) { return 1; } return countDown(int - 1); } function multiplyE
未定义的
代码如下:
var stack = [];
function countDown(int) {
stack.push(int);
if (int === 1) {
return 1;
}
return countDown(int - 1);
}
function multiplyEach() {
// Remove the last value of the stack
// and assign it to the variable int
int = stack.pop();
x = stack.length;
// Base case
if ( x === 0 ) {
return;
}
// Recursive case
else {
stack[int - 1] = int * stack[x - 1];
return multiplyEach(int);
}
}
// Call the function countDown(7)
countDown(7);
// And then print out the value returned by multiplyEach()
console.log(multiplyEach());
非常感谢您的见解
干杯 我认为主要的问题是multilyach()定义中没有参数,但您试图在函数中使用一个参数调用它 类似这样的工作原理:
var stack = [1, 2, 3, 4, 5, 6, 7];
function multiplyEach(arr) {
if (arr.length == 0) {
return 1;
} else {
return arr.pop() * multiplyEach(arr);
}
}
console.log(multiplyEach(stack));
递归函数multiplyEach()中的基本情况返回未定义 这就是你的问题所在 一个简单的解决方案是:
var stack = [];
var multipliedStack = [];
function countDown(int) {
stack.push(int);
if (int === 1) {
return 1;
}
return countDown(int - 1);
}
function multiplyEach() {
// Remove the last value of the stack
// and assign it to the variable int
int = stack.pop();
x = stack.length;
// Base case
if ( x === 0 ) {
return multipliedStack.reverse();
}
// Recursive case
else {
multipliedStack.push(int * stack[x - 1]);
return multiplyEach(int);
}
}
// Call the function countDown(7)
countDown(7);
// And then print out the value returned by multiplyEach()
console.log(multiplyEach());
我不完全明白你说的“有点像阶乘”是什么意思?这个函数到底应该做什么
要理解递归,您需要了解什么是递归基本情况,并且我认为您需要修改代码中没有正确使用的push()和pop()
递归函数通常有点混乱,如果您习惯于迭代,请继续尝试,您会很快适应它。首先要解决的是,从外观上看,multilyeach()函数应该有一个名为int的参数。您正在使用的方法可能更适合于不同的技术,但我们将继续讨论 接下来,在multilyach()中,有两种可能的路径:
void
,或者为返回相乘的值定义int
。然而,在Javascript中,没有不返回值的函数;JS中的“nothing”表示为未定义
。当您返回multilyach()时,您正在将它的另一个调用推送到调用堆栈上,并等待实际返回值。。。结果是return代码>,JS将其解释为返回未定义代码>。同样,在大多数语言中,都会出现某种形式的错误,但在JS中不会!让我们看看两种可能的实现:
您使用的自定义堆栈:
// your stack is fine, so we'll skip to the meat
function multiplyEach() {
var int = stack.pop(), x = stack.length;
stack[x - 1] *= int;
if(x < 2) // to multiply, we need at least two numbers left
return;
multiplyEach();
}
//...
multiplyEach();
console.log(stack[0]);
它们都是递归实现的不同方式;递归本质上要求函数调用自身。另一种可能是让一个参数存储总数,而不是像选项2中那样乘以返回值;这就是所谓的尾部递归
编辑:注意到选项1的基本案例位于错误的位置,所以我移动了它。它现在应该可以工作了。递归地,您可以这样做:
功能多通道(arr、大小){
返回大小===0?arr[size]:arr[size]*multiplyEach(arr,size-1);
}
var数组=[1,2,3,4,5,6,7,8,9];
log(multiplyEach(array,array.length-1))代码>有时递归更适合解决问题,有时迭代更适合解决问题
递归更适合于在满足条件之前执行操作,然后退出,类似于while循环
迭代更适合于执行动作N次,然后退出,类似于for循环
在本例中,我们希望输入一个数组并输出该数组中所有元素的乘积。换句话说,我们要执行N-1乘法,其中N是数组中的元素数。既然我们知道要执行的操作的数量,我们就应该通过下面的迭代来解决问题
var arr = [1, 2, 3]
var result = multiplyEach(arr)
console.log(result)
// -> 6
function multiplyEach(arr) {
var result = 1
arr.map(function(value) {
result *= value
})
return result
}
请记住,上面所说的是一个近似的经验法则,因为有时候递归比迭代更优雅。下面是实阶乘的简单、递归和优雅的实现
function factorial(value) {
return 1 === value ? 1 : value * factorial(value - 1)
}
factorial的迭代实现在while循环形式和for循环形式中都没有那么漂亮
function factorial(value) {
var result = 1
while (value > 0) {
result *= value
value--
}
return result
}
function factorial(value) {
var result = 1
for (var i = 0; i < value; i++) {
result *= value
}
return result
}
函数阶乘(值){
var结果=1
而(值>0){
结果*=值
价值观--
}
返回结果
}
函数阶乘(值){
var结果=1
对于(变量i=0;i
感谢您的见解!这个实现可能会产生不想要的结果,因为在同一个数组上应用函数两次会产生不同的结果,因为JS对传递给FunctionsHanks的所有对象都使用pass-by-reference,但它在Chrome上工作(当然,不是针对任意大小的数组…)。它不会使用同一数组调用函数两次,因为每次调用函数时,我都会弹出一个元素。对吧?这真的很有帮助!谢谢你抽出时间。这很有帮助!谢谢。首先,不要将全局状态用作var堆栈
。您也不应该使用自己的堆栈结构,除非您必须(查看我的)很好地比较概念。备注:1)map
在引擎盖下以循环或递归方式实现。这意味着map
是循环的抽象,而递归是循环的完全替代(实际上递归比循环更具表现力)2)你的阶乘是幼稚的,因为它不是尾部递归,因此必然会炸毁堆栈。
function factorial(value) {
var result = 1
while (value > 0) {
result *= value
value--
}
return result
}
function factorial(value) {
var result = 1
for (var i = 0; i < value; i++) {
result *= value
}
return result
}