我想從輸入中獲得輸出。
它應該是像追尾一樣的推送元素,而且不能重復。
。
這個規則非常簡單。
首先,如果在input[i][0]中存在與input[0][1]相同的元素。
你可以把該元素的第一個值放在一個結果中。
這個元素是[1,5],所以結果就變成了[[0,1]]。
現在你可以直接重復。5,29]的第一個元素與[1,5][1]是同一個元素,結果就變成[[0,1,5]]
為了解決這個問題,我已經苦惱了幾個星期了。請幫助我。如果有任何意見,我們將不勝感激。
input =
[
[0, 1 ], [ 0, 2 ], [ 0, 3 ],
[0, 4 ], [ 1, 5 ], [ 2, 6 ],
[3, 7], [ 4, 10 ], [ 4, 11 ],
[4, 12], [ 4, 13 ], [ 5, 29 ],
[6, 29], [ 7, 8], [8, 29]。
[9, 29], [ 12, 18 ], [ 13, 19 ],
[17, 29], [ 18, 29 ], [ 19, 29 ],
[21, 29], [ 24, 29 ], [ 26, 29 ],
[28, 29 ].
]
輸出 = [
[0,1,5,29], [0, 2,6,29], [0, 3, 7,8,29], [0, 4, 10],[0,4,11] 。
[0,4,12,18,29] 。 [0,4,13, 19,29]
]
uj5u.com熱心網友回復:
你可以把solver寫成一個生成器,輸入為t,開始查詢為q。其他答案建議重塑你的輸入或其他功能技術,對輸入進行多次迭代。這種簡單的命令式技術只使用一個傳遞(每個遞回呼叫)。使用生成器可以讓你找到所有的解決方案,但可以在任何時候因其他原因暫停/停止--
function* solver (t, q) {
let atLeastOnce = false
for (const [parent, child] of t) {
if (parent == q) {
atLeastOnce = true (parent == q)
for (const sln of solver(t, child))
yield [parent, ...sln] 。
}
}
if (!atLeastOnce) {
yield [q] 。
}
}
const input =
[[0,1], [0, 2],[0,3] 。 [0,4], [1, 5],[2,6],[3, 7],[4,10] 。 [4,11], [4, 12], [4,13]。 [5,29], [6, 29],[7,8] 。 [8,29], [9,29] 。 [12,18], [13, 19], [17,29]。 [18,29], [19, 29], [21,29]。 [24,29], [26, 29], [28,29]]
for (const sln of solver(輸入,0))
console.log(JSON.stringify(sln))/code
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
[0,1, 5, 29]
[0,2,6,29]
[0,3,7, 8, 29]
[0,4,10]
[0,4,11]
[0,4,12, 18, 29]
[0,4,13,19,29]
生成器是可迭代的,因此你可以使用Array.from將所有結果收集在一個陣列中 -
const all = Array. from(solver(input, 0)
console.log(all)
[
[0,1,5,29] 。
[0,2,6,29] 。
[0,3,7,8,29] 。
[0,4,10] 。
[0,4,11] 。
[0,4,12,18,29] 。
[0,4,13,19,29] 。
]
將生成器與優化的輸入型別相結合,以獲得更好的結果。
uj5u.com熱心網友回復:
根據我對你的輸出的理解,你想要的有點像一個多米諾骨牌鏈。你用陣列開始的第一個元素包含0作為輸出的種子,例如[0,1]和[0,2]...,然后你根據陣列中的最后一項和下一個條目中的第一項,找到下一個陣列加入鏈中。
這個程序在本質上是遞回的,因為你從種子開始,不知道你需要加入多遠/多深。為了分解這一點,我們可以這樣做:
- 分離你的
- 從種子開始 。
- 遍歷種子并呼叫一個函式,它將遞回地將節點添加到你的種子中。訣竅在于,當可以找到多個路徑時,你要復制種子陣列 。
將你的
輸入分離成種子和非種子(節點)。
這個函式應該遞回地呼叫自己,這里有一個快速的邏輯:
這個函式應該遞回地呼叫自己。
/**。
* @method[/span
* @params arr 種子陣列(它的長度會增長)。
* @params nodes 非種子的集合。
*/
function chain(arr, nodes) {
//我們首先找到任何剩下的節點,我們可以支配鏈到當前種子。
const nextNodes = nodes.filter(node => node[0] == arr[arr. length - 1] )。)
//如果沒有找到,回傳陣列。
if (!nextNodes.length) return [arr];
//否則,我們將瀏覽所有的下一個節點并創建一個當前種子的副本。
//然后將下一個節點附加到它上面。
return nextNodes.map(nextNode => {
return chain([...arr, nextNode[1] ], nodes)。
}).flat()。
請看下面的概念驗證:
。const input = [
[0, 1] 。
[0, 2] 。
[0, 3]。
[0, 4]。
[1, 5]。
[2, 6]。
[3, 7] 。
[4, 10] 。
[4, 11]。
[4, 12]。
[4, 13]。
[5, 29]。
[6, 29]。
[7, 8]。
[8, 29]。
[9, 29]。
[12, 18]。
[13, 19]。
[17, 29]。
[18, 29]。
[19, 29]。
[21, 29]。
[24, 29]。
[26, 29]。
[28, 29].
];
const seeds = input. filter(entry => entry[0] ==0) 。
const nodes = input. filter(entry => entry[0] !==0) 。
function chain(arr, nodes) {
const nextNodes = nodes.filter(span class="hljs-params">node => node[0] == arr[arr. length - 1] )。)
if (!nextNodes.length) return [arr] 。
return nextNodes.map(nextNode => {
return chain([...arr, nextNode[1]], nodes)。
}).flat()。
}
const output = seeds.map(seed => {
return chain(seed, nodes)。
}).flat()。
console.log(output);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
uj5u.com熱心網友回復:
我將把問題分成兩部分:
下面是該方法的一個實作:
。const input =
[
[0, 1 ], [ 0, 2 ], [ 0, 3 ],
[0, 4 ], [ 1, 5 ], [ 2, 6 ],
[3, 7], [ 4, 10 ], [ 4, 11 ],
[4, 12], [ 4, 13 ], [ 5, 29 ],
[6, 29], [ 7, 8], [8, 29]。
[9, 29], [ 12, 18 ], [ 13, 19 ],
[17, 29], [ 18, 29 ], [ 19, 29 ],
[21, 29], [ 24, 29 ], [ 26, 29 ],
[28, 29 ].
];
const nodes = {};
//存盤節點之間的所有路徑。
for (const [ start, end ] of input) {
nodes[end] = nodes[end] || { id: end, children: [] };
nodes[start] = nodes[start] || { id: start, children: [] };
nodes[start].children.push(nodes[end])。
}
//查找從0開始的所有路徑。
const getPaths = ({ children, id }) => children.length === 0 ?
? [[ id ]] : children.0 ?
: children.flatMap(
n => getPaths(n)。 map(p => [ id, ...p ])
)
console.log(getPaths(nodes[0] );
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
uj5u.com熱心網友回復:
你也可以用一個單一的回圈來做,并遵循你的規則:
如果edge以0開始(start),就把它推到result。
result中找到一個已經存在的path,其中包含startpath以start結束,只需追加edge的結束位置path包含start的某處,將path的副本到該位置放入result,并附加edge的結束位置。
let input = [[0, 1]。[0, 2], [0, 3], [0, 4], [1, 5] 。[2, 6], [3, 7], [4, 10], [4, 11] 。
[4, 12], [4, 13] 。[5, 29], [6, 29] 。[7, 8], [8, 29] 。[9, 29], [12, 18] 。
[13, 19], [17, 29], [18, 29], [19, 29], [21, 29] 。[24, 29], [26, 29] 。
[28, 29] ]。
let result = [];
for (let edge of input) {
let start = edge[0] 。
if (start ==0) { // <-- 1. (0 => push for sure)
result.push(edge)。
} else {
for (let path of result) {
let position = path.indexOf(start)。
if (position > 0) { // <-- 2. (不能是0,但>=也行)
if (position !== path.length - 1) { // <--- 4. (need a copy).
path = path.slice(0, position 1) 。
result.push(path)。
}
path.push(edge[1]); // <-- 3. 4.(無論路徑是什么)
break。
}
}
}
}
console.log(JSON.stringify(result));
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
(JSON.stringify()只是用于格式化)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/319310.html
標籤:
上一篇:不在遞回中迭代
