【发布时间】:2021-07-30 16:00:14
【问题描述】:
我正在解决一个问题,我必须找到一个数组的所有可能的子集 (powerSet)。我为此使用递归回溯。我正在使用解决方案来了解递归调用是如何连接的。我无法理解其中的某些部分。例如,这是我要从中创建子集的数组。
var arr = ['apple', 'banana', 'orange'];
我正在使用 Javascript。算法是:在每个递归步骤中,我要么包含当前元素,要么不包含。
解决方法代码如下:
// Code that works
var makeSubset = function (arr) {
var output = []; // Array for storing all the subsets
var subset = function(arr, soFar, idx) { // Helper function
if (idx >= arr.length) {
output.push([...soFar]);
return;
}
soFar.push(arr[idx]);
subset(arr, soFar, idx + 1);
soFar.pop(); // But this works
subset(arr, soFar, idx + 1);
};
subset(arr, [], 0);
return output;
}
console.log(makeSubset(['apple', 'banana', 'ornage']))
// code that does not work
var makeSubset1 = function (arr) {
var output = []; // Array for storing all the subsets
var subset = function(arr, soFar, idx) { // Helper function
if (idx >= arr.length) {
output.push([...soFar]);
return;
}
soFar.push(arr[idx]);
subset(arr, soFar, idx + 1);
soFar = soFar.slice(0, soFar.length - 1);
subset(arr, soFar, idx + 1);
};
subset(arr, [], 0);
return output;
}
console.log(makeSubset1(['apple', 'banana', 'ornage']))
现在,我稍微改变了解决方案,看看它是如何影响的。我没有将修改后的 soFar 数组作为参数传递,而是在外部进行更改。
soFar.push(arr[idx);
由于我更改了 soFar 数组,并且它是一个引用,因此在考虑不包括当前元素时,我撤消了更改。
soFar = soFar.slice(0, soFar.length - 1);
但是上面的行并没有像下面的行那样产生正确的输出。
soFar.pop();
我的问题是:他们不在这里做同样的事情吗?我知道这与参考有关,但我不明白问题出在哪里。此外,在使用引用类型数据结构(如递归回溯中的数组)时的任何一般建议。任何想法将不胜感激。 这是有效的代码 sn-p:
【问题讨论】:
-
它们的工作原理相同,您是否在控制台中遇到错误?
-
这是 soFar.slice() 代码 [ [ 'apple', 'banana', 'orange' ], [ 'apple', 'banana' ], [ 'apple', '香蕉','橙子'],['苹果','香蕉'],['苹果','香蕉','香蕉','橙子'],['苹果','香蕉','香蕉'], [“苹果”、“香蕉”、“香蕉”、“橙子”]、[“苹果”、“香蕉”、“香蕉”]]
-
能否请您提供不起作用的代码的sn-p?现在看到代码混合在一起令人困惑,我们必须了解哪些部分在其中,哪些部分在外面,以便获得故障代码。只需提供两个单独的、可运行的 sn-ps,它们也使用示例输入调用函数,证明一个 sn-p 有效,另一个无效,只需我们运行它。
-
嗨@trincot,我提供了一个包含功能代码和非功能代码的sn-p。请让我知道这是否有帮助。谢谢。
标签: javascript algorithm recursive-backtracking