所以,我正在学习递归,而我正在编写一个编码挑战,需要数组中所有元素的变化。
我被指向Heap's algorithm,这是我迄今为止在JavaScript中制定的内容。
function generate(n, array) {
if (n == 1) {
return array;
}
else {
for (var i = 0; i < n - 1; i++) {
generate(n - 1, array);
if (n % 2 == 0) {
swap(array[i], array[n - 1]);
}
else {
swap(array[0], array[n - 1]);
}
}
generate(n - 1, array);
}
}
请忽略我没有将“swap”实例转换为JavaScript的事实。
我有点不确定如何精确地遍历此算法的递归部分。
说我有阵列: [A,B,C,D,E] 。我相信我将传递给外部函数的论据是:
generate(5, [A,B,C,D,E]);
在这种情况下,n不等于1,所以我将继续“else”部分。 我遇到for循环,因为n是5,它会执行。
下一个:该函数调用自身,但这次参数为:
generate(4, [A,B,C,D,E]);
这就是我的困惑开始的地方:
当我走过这个时,我是否继续前进到“if”/“else”条件 或者我(在递归调用之后)回到外部函数的最开始?
更新
以下是Heap算法的完全翻译的JavaScript版本。
function generate(n, array) {
//console.log("ENTER", n, array)
if (n == 1) {
console.log(array);
}
else {
for (var i = 0; i < n - 1; i++) {
//console.log("RECUR", n-1, array)
generate(n - 1, array);
if (n % 2 == 0) {
//console.log("SWAP ", n, array)
var one = array[i];
var two = array[n - 1];
array[i] = two;
array[n - 1] = one;
//swap(array[i], array[n - 1]);
}
else {
//console.log("SWAP ", 0, n-1)
var first = array[0];
var second = array[n - 1];
array[0] = second;
array[n - 1] = first;
//swap(array[0], array[n - 1]);
}
//console.log("array", array)
}
//console.log("RECUR 2", n-1, array)
generate(n - 1, array);
}
//console.log("LEAVE", n, array)
}
我在纸上走过它,直到我到达了一个重复的位置,[A,B,C,D]。
想到我搞砸了,我决定实施Prune的控制台输出建议,看看控制台发生了什么,这很有帮助。
修正一个小错误之后,现在工作正常。
感谢所有帮助过的人!
答案 0 :(得分:3)
此时我的规范答案是,如果您在纸上查看算法时遇到问题,不要!让电脑为你做。插入一堆 console.log 命令来跟踪执行情况。跟踪每个例程的进入和退出并调用,包括有用的值。
function generate(n, array) {
console.log("ENTER", n, array)
if (n == 1) {
return array;
}
else {
for (var i = 0; i < n - 1; i++) {
console.log("RECUR", n-1, array)
generate(n - 1, array);
if (n % 2 !== 0) {
console.log("SWAP ", n, array)
swap(array[i], array[n - 1]);
}
else {
console.log("SWAP ", 0, n-1)
swap(array[0], array[n - 1]);
}
console.log("array", array)
}
console.log("RECUR 2", n-1, array)
generate(n - 1, array);
}
console.log("LEAVE", n, array)
}
这将为您提供可爱的执行跟踪。为了更好的可读性,缩进每行输出2 *(5-n)空格。
答案 1 :(得分:1)
让我列举你的行,这样我们就可以更容易地引用它们了(见下文)
你从while (rs.next()) {
String value = rs.getString("COLUMN_NAME");
log.info("COLUMN_NAME:"+value)
}
走到generate(5, [A,B,C,D,E]);
(第7行),然后第2次输入generate(4, [A,B,C,D,E]);
,没有完成第一次通话,所以你暂停了第一次通话并开始与第二次通话
现在(第二个电话)generate
所以你再次进入第7行,但这次第3次电话n=4
开始(没有完成之前的电话)
同样适用于第4个电话generate(3, [A,B,C,D,E])
和第5个电话generate(2, ...)
,这是事情开始发生变化的时候
在第5个电话generate(1, ...)
,所以第2行的条件退出为真,并返回n=1
,我们回到我们来自的地方,即第7行的第4个电话,其中什么都没有(它没有分配或任何东西)然后我们到达第8行(第一次),而在第4次调用中,array
因此第二次n=2
发生了swap
增加,然后回到第7行,我们再次调用i
获得相同的结果......依此类推
generate(1, ...)