線
return recursion(target,array) || recursion(target - n, array);
呼叫recursion()
第一與目標總和,並與汽提掉所述第一元件的陣列。如果返回true
(因爲target
爲零且數組爲空),則||
的右側將調用而不是。只有當第一次通話返回undefined
或false
時,纔會進行右側通話。
所以整個過程是首先找到最大的值,然後調用遞歸過程和列表的其餘部分。重複地,遞歸例程撬開第一個值,然後檢查在列表的其餘部分是否存在等於目標的總和或如果總和等於目標減去即撬開第一值在列表的其餘部分。
它有助於略微修改功能,使行爲可以追溯到:
function ArrayAdditionI(arr) {
arr.sort(function(a,b){
return a - b;
});
var largest = arr.pop();
function recursion(target,array){
if(array.length === 0){
return target === 0;
}
var n = array[0];
array = array.slice(1);
console.log("target: " + target + " n: " + n);
var r1 = recursion(target,array), r2 = recursion(target - n, array);
console.log("(" + target + ", " + n + ") left: " + r1 + " right: " + r2);
return r1 || r2;
}
return recursion(largest,arr);
}
如果調用與樣品陣列:
ArrayAdditionI([3,5,-1,8,12]);
你會得到如下跟蹤:
target: 12 n: -1
target: 12 n: 3
target: 12 n: 5
target: 12 n: 8
(12, 8) left: false right: false
target: 7 n: 8
(7, 8) left: false right: false
(12, 5) left: false right: false
target: 9 n: 5
target: 9 n: 8
(9, 8) left: false right: false
target: 4 n: 8
(4, 8) left: false right: false
(9, 5) left: false right: false
(12, 3) left: false right: false
target: 13 n: 3
target: 13 n: 5
target: 13 n: 8
(13, 8) left: false right: false
target: 8 n: 8
(8, 8) left: false right: true
(13, 5) left: false right: true
target: 10 n: 5
target: 10 n: 8
(10, 8) left: false right: false
target: 5 n: 8
(5, 8) left: false right: false
(10, 5) left: false right: false
(13, 3) left: true right: false
(12, -1) left: false right: true
因此,||
的左側表示意願查看是否可以在考慮其中一個值時找到而沒有的總和,並且右側考慮您是否可以找到總和,假定其中一個值是其中一個組成部分。從前幾行開始,您會看到遞歸跳過前四個值,從最小到最大,直到最後一次調用的數組爲空。目標值仍然是12
,所以這沒有奏效。
然後是包含價值的嘗試5
(當target
是12
),給人的7
的目標,並與剛剛8
它的列表;那也不管用。繼續,只有當流程到達原始調用的右側時,target
爲12
和n
爲-1
,事情纔開始查找。因爲12 - -1
是13
,並且13 - 5
是8
,並且8 - 8
是0
,所以有一組值總計到目標。
雖然不完全一樣,我鼓勵你看看[從雄辯的Javascript的Javascript遞歸(http://stackoverflow.com/q/26205376/1048572)以及從那裏鏈接的其他問題 – Bergi
請注意,'||'運算符沒有特別與遞歸的概念有關。 – Pointy