我希望这不是一个重复的问题 - 尽管我在这方面找不到多少帮助。
我正在练习递归函数(我是新手),我正在尝试将数组中的每个数相乘。有点像阶乘。我有这个代码,但结果只返回undefined
。
以下是代码:
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());
非常感谢您的任何见解。
干杯!
答案 0 :(得分:2)
要解决的第一件事是你的multiplyEach()函数应该有一个名为int的参数,从它的外观来看。您使用的方法可能更适合不同的技术,但我们会做到这一点。
接下来,在multiplyEach()中,有两种可能的路径:
堆栈仍然有元素,在这种情况下,我们将堆栈上的新顶值乘以旧的值,然后继续运行另一个multiplyEach。
堆栈是空的,我们只是返回。
这里的问题是我们实际上并没有返回最终的堆栈值,或者将它留在那里以便稍后访问。我们已经有效地丢失了它,那么输出的功能是什么?
在许多语言中,我们会为此函数定义一个返回类型,void
表示无值,或int
表示返回乘法值。但是,在Javascript中,没有函数不会返回值; "无"在JS中表示为undefined
。当你返回multiplyEach()时,你再次将它调用到调用堆栈上,并等待一个实际的返回值......最终为return;
,JS解释为return undefined;
}。同样,在大多数语言中,会出现某种形式的错误,但不会出现在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]);
使用参数并使用列表:
function multiplyEach(index) {
var int = list[index];
if(index == 0)
return int;
return int * multiplyEach(index - 1);
}
//...
console.log(multiplyEach(list.length - 1));
他们以递归方式实现这两种方式;所有递归固有地要求函数调用自身。另一种可能性是使用参数存储总数,而不是像选项2中那样乘以返回值;那被称为尾递归。
编辑:注意到选项1的基本情况是在错误的地方,所以我移动了它。它现在应该工作。
答案 1 :(得分:1)
递归地你可以这样做:
function multiplyEach(arr, size) {
return size === 0 ? arr[size] : arr[size] * multiplyEach(arr, size - 1);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(multiplyEach(array, array.length - 1));
但你可以使用原生方法reduce来做,然后你可以做到这一点:
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9].reduce(function(a, b) { return a * b; }));
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9].reduce((a, b) => a * b));
我希望它有所帮助。
答案 2 :(得分: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循环形式和循环形式中并不相同。
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
}
答案 3 :(得分:0)
我认为主要问题是你在multiplyEach()定义中没有参数,但你试图在函数内部调用一个参数。
这样的工作:
public void setLetterNotNew(int letterId) {
final String sql = "UPDATE income SET isnew=? WHERE id=?";
try( Connection con = HikariFactory.getConnection(); PreparedStatement ps = con.prepareStatement(sql); ) {
ps.setInt(1, 0);
ps.setInt(2, letterId);
int i = ps.executeUpdate();
if(i==0) throw new SQLException("setLetterNotNew");
} catch (SQLException e) {
log.error(e);
}
}
答案 4 :(得分:0)
递归函数multiplyEach()中的基本情况返回undefined。
这就是你的问题所在。
一个简单的解决方法是:
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()。
如果你习惯于迭代,递归函数通常会让人感到困惑,继续尝试,你会很快习惯它。