我试图编写一个反转列表的函数。该函数是递归的。
我知道javascript没有TCO,但我还想尝试这个:
reverse = function(list) {
if (list.length < 2) { return list }
fk = fork(list);
return reverse(fk.tail).concat([fk.head])
}
fork
函数将列表拆分为头部和尾部:
fork = function(list) {return {head: list[0], tail: list.slice(1)}}
当我使用列表reverse()
来呼叫[1,2,3,4,5]
时,我得到了这样的结果:
reverse([1,2,3,4,5]) // [5,4,4,4,4]
不确定我在这里做错了什么。预期结果为[5,4,3,2,1]
。
请帮忙。
答案 0 :(得分:6)
你应该提取代码,这对你有很大的帮助。特别是,此代码失败,因为fk
被视为全局变量。如果您使用var
作为前缀,则可以使用:
var reverse = function(list) {
if (list.length < 2) { return list }
var fk = fork(list);
return reverse(fk.tail).concat([fk.head])
}
就目前而言,在每次递归调用时,您都会修改相同的fk
变量,这实际上意味着将同一fk.head
- 最后一个之前的元素连接起来。
事实上,你甚至不需要临时变量:
function recursive_reverse(list) {
return list.length < 2 ? list : recursive_reverse(list.slice(1)).concat([list[0]]);
}
至于尾递归,这是一种可能的方法:
function recursive_reverse(list) {
return tail_recursive_reverse(list, []);
}
function tail_recursive_reverse(list, res) {
if (!list.length) return res;
var head = list[0];
var tail = list.slice(1);
res.unshift(head);
return tail_recursive_reverse(tail, res);
}