为什么我的置换算法会为所有排列提供相同的结果?

时间:2017-08-10 21:17:45

标签: javascript arrays algorithm heap permutation

这是我第一次在SO上提出问题。我总能找到解决大部分问题的答案,但这次我坚持使用堆的排列算法。我一直试图解决这个挑战一段时间没有成功,所以我来找你们比我更有编程知识的人。

我编写了一些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);
        }
    }
};

1 个答案:

答案 0 :(得分:2)

这是简单(堆)引用与(堆栈)值问题。原因很简单:所有递归调用中的arr引用内存中的相同数组。因此,当您调用newArr.push(arr)时,会将另一个对同一对象的引用添加到结果列表中。当您执行swap时,您将newArr的所有元素交换元素,因为它们指向同一个数组。有关可能的解决方法,另请参阅Copying array by value in JavaScript。 (基本上使用Array.slice方法创建独立副本。)