簡體   English   中英

排列Javascript

[英]Permutation Javascript

所以我現在有了這段代碼,在輸入中,我的名字字母“ ahimrsu”以升序排列。 我需要為所有組合中的“ mariush”顯示正確的數字,應該是2170。目前,它僅顯示ahimrsu,ahimrus,ahimsru,ahimsur,ahimurs,ahimusr,ahirmus,ahirmsu .....等等我該怎么辦這個?

<!DOCTYPE HTML>

<html>
<head>
<!--Script Function Start Here-->
<script type="text/javascript">
        function perms(data) {
    if (!(data instanceof Array)) {
        throw new TypeError("input data must be an Array");
    }

    data = data.slice();  // make a copy
    var permutations = [],
        stack = [];

    function doPerm() {
        if (data.length == 0) {
            permutations.push(stack.slice());
        }
        for (var i = 0; i < data.length; i++) {
            var x = data.splice(i, 1);
            stack.push(x);
            doPerm();
            stack.pop();
            data.splice(i, 0, x);
        }
    }

    doPerm();
    return permutations;
}

var input = "ahimrsu".split('');
var result = perms(input);
for (var i = 0; i < result.length; i++) {
    result[i] = result[i].join('');
}
console.log(result);
</script>
<!--Header start here-->
</head>
<body>
<!--Script Result-->
<script type="text/javascript">
        document.write(result);
</script>

</body>
</html>

使用遞歸步驟,用於字符串置換的算法會稍微復雜一些(盡管可以進行編碼而無需遞歸)。

下一個javascript實現基於此答案中算法的描述:

  1. 刪除第一個字母
  2. 查找剩余字母的所有排列(遞歸步驟)
  3. 重新插入在每個可能的位置刪除的字母。

實現然后是這樣的:

function permutation(str) {

    if (str.length == 1) {
        return [str];
    }

    var first = str[0],  // Step #1
        perms = permutation(str.slice(1)), // Step #2
        result = [];

    // Step #3
    for (var i = 0; i < perms.length; i++) {
        for (var j = 0; j <= perms[i].length; j++) {
            result.push( perms[i].slice(0, j) + first + perms[i].slice(j) );
        }
    }

    return result;
}

console.log(permutation('ahimrsu'));

上面的實現給出了5040個組合,這似乎是正確的,因為7! == 5040(排列數是字符數的階乘)。

現在,當您擁有所有可能的排列數組時,您可以輕松找到特定的字符串出現:

var combinations = permutation('ahimrsu'); 
var index = combinations.indexOf('mariush'); // Index of the "mariush"
alert('"mariush" is the ' + (index + 1) + 'th permutation of "ahimrsu".');

這是我從以下答案中得出的解決方案: https : //stackoverflow.com/a/18879232/783743

var permute = (function () {
    return permute;

    function permute(list) {
        return list.length ?
            list.reduce(permutate, []) :
            [[]];
    }

    function permutate(permutations, item, index, list) {
        return permutations.concat(permute(
            list.slice(0, index).concat(
            list.slice(index + 1)))
            .map(concat, [item]));
    }

    function concat(list) {
        return this.concat(list);
    }
}());

您可以使用permute函數查找數組的所有排列:

var array = "ahimrsu".split("");
var permutations = permute(array).map(join);
var index = permutations.indexOf("maruish");

function join(array) {
    return array.join("");
}

該算法很容易理解:

  1. 我們想要一個[a] -> [[a]]類型的函數permute (即給定a s的列表,它返回輸入的置換列表)。
  2. 給定一個空列表( [] )作為輸入,則輸出為排列的空列表( [[]] )。
  3. 否則,對於每個元素:
    1. 我們從列表中刪除該元素。
    2. 我們遞歸地找到其余元素的排列。
    3. 我們將刪除的元素添加到每個排列的開頭。

例如,假設我們要查找數組[1, 2, 3]的排列:

1. permute([1, 2, 3]) === [1, 2, 3].reduce(permutate, [])
    1. permutate([], 1, 0, [1, 2, 3])
        1. permute([2, 3]) === [2, 3].reduce(permutate, [])
            1. permutate([], 2, 0, [2, 3])
                1. permute([3]) === [3].reduce(permutate, [])
                    1. permutate([], 3, 0, [3])
                        1. permute([]) === [[]]
                        2. [[]].map(concat, [3]) === [[3]]
                        3. [].concat([[3]]) === [[3]]
                2. [[3]].map(concat, [2]) === [[2, 3]]
                3. [].concat([[2, 3]]) === [[2, 3]]
            2. permutate([[2, 3]], 3, 1, [2, 3])
                1. permute([2]) === [2].reduce(permutate, [])
                    1. permutate([], 2, 0, [2])
                        1. permute([]) === [[]]
                        2. [[]].map(concat, [2]) === [[2]]
                        3. [].concat([[2]]) === [[2]]
                2. [[2]].map(concat, [3]) === [[3, 2]]
                3. [[2, 3]].concat([[3, 2]]) === [[2, 3], [3, 2]]
        2. [[2, 3], [3, 2]].map(concat, [1]) === [[1, 2, 3], [1, 3, 2]]
        3. [].concat([[1, 2, 3], [1, 3, 2]]) === [[1, 2, 3], [1, 3, 2]]
    2. permutate([[1, 2, 3], [1, 3, 2]], 2, 1, [1, 2, 3])
        1. permute([1, 3]) === [1, 3].reduce(permutate, [])
        2. [[1, 3], [3, 1]].map(concat, [2]) === [[2, 1, 3], [2, 3, 1]]
        3. [[1, 2, 3], [1, 3, 2]].concat([[2, 1, 3], [2, 3, 1]])
    3. permutate([[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]], 3, 2, [1, 2, 3])
        1. permute([1, 2]) === [1, 2].reduce(permutate, [])
        2. [[1, 2], [2, 1]].map(concat, [3]) === [[3, 1, 2], [3, 2, 1]]
        3. [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]].concat([[3, 1, 2], [3, 2, 1]])

舊的解釋:

  1. 首先,我們刪除列表的第一個元素。 因此,我們有項目1和列表[2, 3]
    1. 接下來,我們找到[2, 3]的排列。
      1. 我們刪除第一個元素。 因此,我們有項目2和列表[3]
        1. 接下來,我們找到[3]的排列。
          1. 我們刪除第一個元素。 因此,我們有項目3和列表[]
            1. 接下來,我們找到[]的排列,即[[]]
          2. 我們在每個排列的開頭加3
          3. 結果是[[3]]
        2. 我們在每個排列的開頭加2
        3. 結果是[[2, 3]]
      2. 我們刪除第二個元素。 因此,我們有項目3和列表[[2]]
        1. 接下來,我們找到[2]的排列。
          1. 我們刪除第一個元素。 因此,我們有項目2和列表[]
            1. 接下來,我們找到[]的排列,即[[]]
          2. 我們在每個排列的開頭加2
          3. 結果是[[2]]
        2. 我們在每個排列的開頭加3
        3. 結果是[[3, 2]]
      3. 我們將兩個兩個列表合並。
      4. 結果是[[2, 3], [3, 2]]
    2. 我們在每個排列的開頭加1
    3. 結果為[[1, 2, 3], [1, 3, 2]]
  2. 第二個元素相同:項目2和列表[1, 3]
  3. 第三個元素相同:項目3和列表[1, 2]
  4. 我們結合了三個列表。
  5. 結果為[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

觀看演示:

 var permute = (function () { return permute; function permute(list) { return list.length ? list.reduce(permutate, []) : [[]]; } function permutate(permutations, item, index, list) { return permutations.concat(permute( list.slice(0, index).concat( list.slice(index + 1))) .map(concat, [item])); } function concat(list) { return this.concat(list); } }()); var array = "ahimrsu".split(""); var permutations = permute(array).map(join); var index = permutations.indexOf("maruish"); alert("maruish is the " + (index + 1) + "th permutation of ahimrsu."); function join(array) { return array.join(""); } 

希望能有所幫助。

好吧,如果我們使用您的訂購方案,“ mariush”實際上是排列2220:

 /*jslint white: true*/ var perm = function(s){ 'use strict'; if(s.length === 1){ return [s]; } // For each character c in s, generate the permuations p of all // the other letters in s, prefixed with c. return [].reduce.call(s, function(p,c,i){ // permutations, char, index var other = s.slice(0,i) + s.slice(i+1); return p.concat(perm(other).map(function(oneperm){ return c + oneperm; })); }, []); }; alert(perm('ahimrsu').indexOf('mariush') + 1); // 2220 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM