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

时间:2019-04-02 07:23:21

标签: javascript recursion

因此,我编写了此函数,该函数使用递归求和一个数字数组。我将如何优化此尾部呼叫?

function sum(array) {
  if (array.length === 0) {
    return 0;
  } else {
    return array[0] + sum(array.slice(1));
  }
}

sum([1, 2, 3, 4, 5]); // 15

4 个答案:

答案 0 :(得分:3)

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

因此,您还需要在函数中将total存储为参数,并在递归开始时移交该值。

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

答案 1 :(得分:0)

使用Array.prototype.reduce()无需执行递归功能:

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

console.log(result);

答案 2 :(得分:0)

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

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]));

答案 3 :(得分:0)

您不能,大多数浏览器不支持尾部调用优化(TCO)。您可以看到支持信息here

您始终可以使用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");