在所有可能的排列列表中查找给定字符串的排名

时间:2013-07-11 18:34:16

标签: javascript performance algorithm ranking

我试图在可能的排列列表中找到给定字符串的Rank。我试图提出一个解决方案,试图找到所有可能的排列,为它们分配排名,然后显示它。

但是当字符串的长度不断增加时,这会大大降低性能。所以想知道是否有人能想出这个问题的有效解决方案。

function permute(str) {
    // Sort the string
    var arr = [];
    for (var i = 0; i < str.length; i++) arr.push(str[i]);
    var sortedString = arr.sort().join(''),
        // Length of the string
        length = str.length,
        used = [];
    // Create a boolean array for length of the string
    while (length--) used.push(false);
    // String buffer that holds the current string
    var out = '';
    // Call the function
    doPermute(sortedString, str, out, used, str.length, 0);
}
var count = 0;

function doPermute(inp, givenString, out, used, length, level) {
    // Only if length of the string equal to current level print it
    // That is permutation length is eqaul to string length
    if (level == length) {
        count++;
        //console.log('Perm :: ' + out + ' -- ' + count);
        if (out === givenString) {
            var pp = 'Rank of  :: ' + out + ' -- ' + count;
            $('div').append('<p>' + pp + '</p>');
        }
        return;
    }
    for (var i = 0; i < length; ++i) {
        // If variable used continue
        if (used[i]) continue;
        // Append the current char in loop
        out += inp[i];
        // set variable to true
        used[i] = true;
        // Call the function again
        doPermute(inp, givenString, out, used, length, level + 1);
        // Set it to false as the variable can be reused
        used[i] = false;
        // remove the last character of the buffer
        out = out.slice(0, out.length - 1)
    }
}

permute('dbcarf')

Fiddle

2 个答案:

答案 0 :(得分:2)

当然:如果输入字符串是"cab". 从c开始的字符串可以得到的最低等级是什么?

<强> C 注意它之前的字符串。

abc
acb
bac
bca

因此,以c开头的字符串具有最小等级5.这只是输入字符串中在c之前按字典顺序排列的字符数(按顺序a,b,c,d,e,f ......)所以我们有2.以字母开头的每个单词可以有2个单词 下一个字母是“a”?
以“ca”开头的单词的最低等级是多少? 5
为什么呢?
“a”是我们用剩余字母填充第二个位置的最佳方式 第三个元素“b”也是如此 所以“出租车”的等级是5.

总的来说。(假设没有重复,虽然这并不难),

var W; //input string
 var C[26];
 var rank = 1;
 for (var i = 0; i < W.length; i++) C[W[i] - 'a']++;
 for (var i = 0; i < W.length; i++) {
     //How many characters which are not used, that come before current character
     var count = 0;
     for (var j = 0; j < 26; j++) {
         if (j == (W[i] - 'a')) break;
         if (C[j] > 0) count++;
     }
     C[W[i] - 'a'] = 0;
     rank += count * fact(W.length - i - 1);
 }

答案 1 :(得分:0)

https://en.wikipedia.org/wiki/Permutation#Numbering_permutations中有一个解释如何将n个对象的置换转换为0..n!-1范围内的数字,并继续说“将连续的自然数转换为阶乘数字系统以字典顺序产生这些序列(如同任何混合基数系统的情况),并进一步将它们转换为排列保留了字典顺序,前提是使用了Lehmer代码解释“所以我会尝试进行这个数字转换并查看如果它根据你的定义产生与你需要的等级相关的东西。