为啥我的排列算法对所有排列都给出相同的结果?
Posted
技术标签:
【中文标题】为啥我的排列算法对所有排列都给出相同的结果?【英文标题】:Why is my permutation algorithm giving me the same result for all permutations?为什么我的排列算法对所有排列都给出相同的结果? 【发布时间】:2018-01-19 06:51:21 【问题描述】:我被一些堆的排列算法困住了。我编写了一些 javascript 代码以递归方式查找值的所有可能排列:数组或字符串。当我console.log()
置换值时,我的代码似乎可以完美运行,但是当我将它们推送到另一个数组时,我得到的所有值都相同。我很困惑。
我的代码包含两个独立的函数:一个是交换元素,另一个是递归查找可能的排列:
arr = ["a", "b", "c"];
newArr = [];
// swap mechanism here
function swap(arr, pos1, pos2)
var temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
;
function perm(arr, nArr, n)
n = n || arr.length;
if (n === 1)
console.log(arr); // console.log() works great
newArr.push(arr); // pushing the permuted values does not
else
for(var i = 1; i <= n; i += 1)
perm(arr, nArr, n - 1);
if (n % 2)
var j = 1;
else
var j = i;
swap(arr, j - 1, n - 1);
;
【问题讨论】:
欢迎来到 ***。请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。 【参考方案1】:这是一个简单的(堆)引用与(堆栈)值的问题。原因很简单:arr
在所有递归调用中都引用了内存中的同一个数组。因此,当您调用newArr.push(arr)
时,对同一对象的另一个引用将添加到结果列表中。而当您执行swap
时,您会将元素交换为newArr
的所有元素,因为它们指向同一个数组。另请参阅Copying array by value in JavaScript 了解可能的解决方法。 (基本上是用Array.slice
的方法来创建一个独立的副本)。
【讨论】:
非常感谢,兄弟。我很困惑,但我想我明白问题所在。一个快速的问题:console.log() 怎么会显示所有排列的值?我不太明白那部分。 @WadsonFourrien,console.log
显示执行时的当前值。那时(唯一的)数组处于您想要的状态(并且来自newArr
的所有引用都指向该状态下的同一个数组)。但是,当您下次调用swap
时修改该(相同的)数组,它的状态现在与您上次记录的不同。设置断点并在第 3 次或第 4 次迭代中查看 newArr
以了解它如何包含对同一内存的多个引用可能会有所帮助。以上是关于为啥我的排列算法对所有排列都给出相同的结果?的主要内容,如果未能解决你的问题,请参考以下文章