我一直在閱讀多篇文章,一旦我遞回地做某事,我就是不明白,我了解基本情況,但我沒有得到遞回步驟。所以我有這個代碼,這是我找到的解決方案。
function range (start, end) {
if (end < start) return [];
if(start == end) {
return [start];
}
else {
const numbers = range(start , end - 1);
numbers.push(end)
return numbers;
}
}
所以,我理解開始 == 結束,這是我沒有得到的。
為什么數字是一個陣列?我看不到范圍是陣列的任何地方,我也不明白如果我使用 start 1 并按下 start,數字是向后的。到目前為止,我已經花了 3 周的時間試圖更好地掌握遞回,但就是做不到,如果有人可以幫我解釋一下,也許可以提供一些我沒有找到的資源?我看了 Al Sweigarts 遞回視頻,并認為我理解它,直到我去做某事,我發現它的遞回步驟正在摧毀我,我正在盡我所能理解并了解它是如何作業的,但我在這一點上,我對自己非常沮喪。感謝您的任何幫助。
uj5u.com熱心網友回復:
見行內評論:
function range (start, end) {
console.log("range function is running with arguments of: ", start, end);
// If end < start, exit function and return an empty array
if (end < start) return [];
// If not, check if start and end are equal (with conversion)
if(start == end) {
// If so, return an array that only contains the start parameter value and exit
return [start];
} else {
// If the above tests are false, call the function again
// but with end being one less than before and assign either
// array from above as the value of numbers.
const numbers = range(start , end - 1);
numbers.push(end); // Add end to the end of the array
return numbers; // Return this array instead of the other 2
}
}
console.log("Final array is: ",range(10,20)); // Display the final returned array
uj5u.com熱心網友回復:
唯一可能range在這里回傳的是[]哪個是陣列,[start]哪個也是陣列。因此,當您range從 else 塊遞回呼叫時,您總是會得到一個陣列,因為代碼沒有任何其他路徑可以走。
uj5u.com熱心網友回復:
您無法通過僅閱讀其行來理解遞回演算法(不是您自己的)。因此,您需要應用一個簡單的示例來獲得正確的結果并了解它的去向,這是我的示例:
第一次通話
開始 = 1
結束 = 0
=>開始>開始演算法結果:return []; ===>一個空陣列
第一次通話
開始 = 1
結束 = 1
=> start = end 演算法結果: return [start]; ===> ONE 元素陣列(起始值)
第一次通話
開始 = 1
結束 = 5
=> 開始 < 結束
在這種情況下,演算法將 const numbers = range(start , end - 1);通過更改最終值并將其存盤在名為 numbers 的陣列中來呼叫自身
第二次呼叫:
數字 = []
范圍(1,5-1)
(不要忘記,“end”(4)仍然大于“start”,所以它會進入召回迭代)
第三次呼叫:
數字 []
范圍(1,4-1)
=>"end" 仍然更大 (3)
第四次呼叫:
數字 []
范圍(1,3-1)
=>"end" 仍然更大 (2)
第五次呼叫: numbers [] range(1,2-1)
=>現在,“end”(1)等于“start”(1),下一次迭代將采取不同的行動
第六次呼叫: start = end ==>這個呼叫將回傳起始值(1)并將其推送到常數
所以,現在,演算法將在之前的呼叫之后繼續執行未執行的行(我的意思是數字 push() ):
它的結果sixth call = 1
會將其推送到數字,并回傳數字(一個元素的陣列 [1])fifth call = 2
推送到數字的結果 ==> 數字是 [1,2] 等。直到它到達第一個呼叫。
最終結果:[1,2,3,4,5]
我希望它能有所幫助。
uj5u.com熱心網友回復:
域和共域
函式的輸入稱為域,函式的回傳型別稱為codomain。這些型別可以在撰寫實作時有效地指導我們——
range : (number, number) -> number array
填空
這個有用的模板可以讓你開始使用幾乎所有的遞回函式。一開始可能看起來很有挑戰性,但隨著我們填寫這些內容,事情變得更加容易。根據 for 的型別range,我們已經知道2并且3 必須回傳一些陣列 -
// range : (number, number) -> number array
function range(start, end) {
if (...) // 1
return ... // 2 (must return array)
else
return ... // 3 (must return array)
}
1. 基本情況
每個遞回函式都需要一個基本情況,這不會導致遞回呼叫,從而允許函式最終退出。函式在什么條件下range退出?
// range : (number, number) -> number array
function range(start, end) {
if (start > end) // 1 ? when start exceeds end, exit
return ... // 2
else
return ... // 3
}
2. 基值
當滿足退出條件時,我們需要回傳基值。通常它是我們函式回傳型別或 codomain 的空值。既然我們必須回傳一個陣列,那么陣列的空值是什么?
// range : (number, number) -> number array
function range(start, end) {
if (start > end) // 1 ?
return [] // 2 ? an empty array is []
else
return ...
}
3. 歸納案例
我們必須指定當分支中不滿足退出else條件時會發生什么,稱為歸納案例。如果start > end不是true,通過歸納我們知道start <= end。在這種情況下,我們解決當前start和的問題stop,并將其添加到較小子問題的結果中。換句話說,如果我range(P,Q)的答案是——
prepend P to the result of range(P 1, Q)
記住 for 的型別range給了我們一個提示。當range使用新引數呼叫時,第一個和第二個引數都是number. 回傳值將是一個數字陣列,或number array.
在 JavaScript 中,我們將其寫為 -
// range : (number, number) -> number array
function range(start, end) {
if (start > end) // 1 ?
return [] // 2 ?
else
return [start, ...range(start 1, end)] // 3 ?
}
替代模型
遞回是一種函式式遺產,因此將其與函式式風格一起使用會產生最佳結果。這意味著撰寫具有參考透明性的函式,這意味著沒有可觀察到的副作用,并且當使用相同的輸入時,函式將始終回傳相同的值。使用替換模型,我們可以將任何函式呼叫替換為其回傳值 -
range(3,6)
[3, ...range(3 1, 6)]
[3, ...range(4, 6)]
[3, ...[4, ...range(4 1, 6)]]
[3, ...[4, ...range(5, 6)]]
[3, ...[4, ...[5, ...range(5 1, 6)]]]
[3, ...[4, ...[5, ...range(6, 6)]]]
[3, ...[4, ...[5, ...[6, ...range(6 1, 6)]]]]
[3, ...[4, ...[5, ...[6, ...range(7, 6)]]]]
[3, ...[4, ...[5, ...[6, ...[]]]]] // base case met
[3, ...[4, ...[5, ...[6]]]]
[3, ...[4, ...[5, 6]]]
[3, ...[4, 5, 6]]
[3, 4, 5, 6]
上面的任何行都可以評估,我們將始終收到相同的輸出。
演示
function range(start, end) {
if (start > end)
return []
else
return [start, ...range(start 1, end)]
}
console.log(range(3,6))
// [3, 4, 5, 6]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/489922.html
標籤:javascript 递归
