簡體   English   中英

我如何編寫一個遞歸函數,該函數對使用尾調用優化(TCO)的數字數組求和?

[英]How would I write a recursive function that sums an array of numbers that uses tail call optimization (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也存儲在函數中作為參數,並在遞歸時移交此值。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM