我将如何编写一个递归函数,对使用尾部调用优化 (TCO) 的数字数组求和?



所以我写了这个函数,它使用递归对数字数组求和。如何优化此尾部调用?

function sum(array) {
if (array.length === 0) {
return 0;
} else {
return array[0] + sum(array.slice(1));
}
}
sum([1, 2, 3, 4, 5]); // 15

TCO 函数需要返回函数调用,该调用将替换最后一个堆栈项并防止堆栈增长。

因此,您需要将total以及作为参数存储在函数中,并在递归的 ent 处交出此值。

function sum(array, total = 0) {
if (array.length === 0) {
return total;
} 
return sum(array.slice(1), total + array[0]);
}
console.log(sum([1, 2, 3, 4, 5])); // 15

使用 Array.prototype.reduce() 不需要做递归函数:

const result = [1, 2, 3, 4, 5].reduce((a, c) => a + c, 0); // 15
console.log(result);

只需使用三元运算符,如下所示:

const sum = array => array.length ? array[0] + sum(array.slice(1)) : 0;
console.log(sum([1, 2, 3, 4, 5])); // 15

您还可以使用Array.prototype.reduce来避免递归:

const sum = array => array.reduce((acc, curr) => acc + curr, 0);
console.log(sum([1, 2, 3, 4, 5]));

你不能,大多数浏览器不支持尾调用优化(TCO)。您可以在此处查看支持信息。

你总是可以使用 for 循环。 for 循环在大多数情况下具有更高的性能。

function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}
function sum_1(arr) {
var s = 0;
for (var i = 0; i < arr.length; i++) {
s += arr[i];
}
return s;
}
function sum_2(arr){
return arr.reduce((a, c) => a + c, 0);
}
var arr = [];
for (var i = 0; i < 10000000; i++) {
arr[i] = getRandomInt(0,100);
}
let t0 = window.performance.now();
sum_1(arr); // 15
let t1 = window.performance.now();
console.log("sum_1 executed time : " + (t1 - t0) + " ms");
let t2 = window.performance.now();
sum_2(arr); // 15
let t3 = window.performance.now();
console.log("sum_2 executed time : " + (t3 - t2) + " ms");

最新更新