Javascript递归置换生成器

时间:2015-08-11 18:59:26

标签: javascript recursion permutation

我试图在Javascript中实现递归排列生成器,但我似乎无法通过所有递归分支(请参阅下面的结果)。

我知道我错过了重要的事情,有人可以帮我理解我出错的地方吗?

    var permute = function(input){
        var permutation = function (arr, position){
            if(position >= arr.length-1){
                results.push(arr);
            }else{
                var tempSwap="";
                for(i=position;i<arr.length;i++){
                    tempSwap = arr[position];
                    arr.splice(position,1,arr[i]);
                    arr.splice(i,1,tempSwap);
                    permutation(arr,(position+1));
            }
            return;
        }
    };

    permutation(input,0);
};

var results=[];
permute(['a','b','c']);
console.log(results);

结果: [[&#39; a&#39;,&#39; c&#39;,&#39; b&#39; ],[&#39; a&#39;,&#39; c&#39;,&#39; b&#39; ]]

2 个答案:

答案 0 :(得分:1)

有两个错误:你正在处理同一个数组而没有复制,你的循环计数器i是一个全局变量。固定代码:

 var permute = function(input){
        var permutation = function (arr, position){
            if(position == arr.length-1){ // >= was redundant and confusing
                results.push(arr);
            }else{
                for(var i=position;i<arr.length;i++){ // use local i
                    var tempSwap = arr[position];
                    arr.splice(position,1,arr[i]);
                    arr.splice(i,1,tempSwap);
                    permutation(arr.slice(),(position+1)); // you need a copy here
            }
            return;
        }
    };

    permutation(input,0);
};

var results=[];
permute(['a','b','c']);
console.log(results.join(' ')); // a,b,c a,c,b b,a,c b,c,a c,a,b c,b,a

https://jsfiddle.net/sagqkchL/1/

不进行复制会导致所有结果数组看起来都一样。全局变量仅产生了2个结果。

答案 1 :(得分:0)

  

我知道我错过了重要的

您的i变量为implictly global。用var声明它,你的基本问题就会消失。

此外,正如评论中所提到的,您不是要复制input数组,因此您始终要修改同一个对象(并最终使用result[0] == result[1] == …);你过早地结束你的递归(基本情况是你遇到结束时,而不是之前);您还应该在results函数中创建permute数组。

function permute(input){
    function permutation(arr, position){
        if(position >= arr.length) {
            results.push(arr);
        } else {
            permutation(arr, position+1); // nothing is swapped, no need to copy anything
                                          // you can also omit this line and start i=position
            for (var i=position+1; i<arr.length; i++) {
                var tmp = arr.slice();
                tmp[position] = arr[i];
                tmp[i] = arr[position];
                permutation(tmp, position+1);
            }
        }
    };
    var results = [];
    permutation(input, 0);
    return results;
};

console.log(permute(['a','b','c'])); // [["a","b","c"],["a","c","b"],["b","a","c"],["b","c","a"],["c","b","a"],["c","a","b"]]