递归生成字符串排列;每个字符出现n次

时间:2015-11-24 23:07:49

标签: string algorithm recursion permutation

我正在尝试编写一个算法,该算法将生成长度为nm的所有字符串,其中每个数字都是n,n,...,

例如,所有长度为6的字符串,恰好有两个1,两个2和两个3,例如112233,121233,

我设法使用递归方法只使用1和2进行此操作,但是当我引入3时,似乎无法获得有效的东西。

当m = 2时,我的算法是:

generateAllStrings(int len, int K, String str) 
{
    if(len == 0) 
    {
        output(str);
    }

   if(K > 0) 
   {
       generateAllStrings(len - 1, K - 1, str + '2'); 
    }      
   if(len > K)  
   {
        generateAllStrings(len - 1, K, str + '1'); 
    }
}

我尝试为第三个数字插入类似的条件,但算法没有给出正确的输出。在那之后,我甚至不知道如何推广4个及以上的数字。

递归是正确的吗?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

一个选项是列出字符串111...1222...2...nnn....n的所有不同排列。有很好的算法可以在时间上与字符串的长度成比例地枚举字符串的所有不同排列,它们可能是解决这个问题的好方法。

答案 1 :(得分:0)

您可以使用DFS(或BFS)轻松完成此操作。我们可以定义一个图形,使得每个节点包含一个字符串,并且一个节点连接到任何节点,该节点包含与原始字符串相比具有一对int交换的字符串。这个图是连接的,因此我们可以很容易地生成一组所有节点;它将包含所有搜索的字符串:

set generated_strings
list nodes

nodes.add(generateInitialString(N , M))
generated_strings.add(generateInitialString(N , M))

while(!nodes.empty())
    string tmp = nodes.remove(0)

    for (int i in [0 , N * M))
        for (int j in distinct([0 , N * M) , i))
            string new = swap(tmp , i , j)
            if (!generated_strings.contains(new))
                nodes.add(new)
                generated_strings.add(new)

//generated_strings now contains all strings that can possibly be generated.

答案 2 :(得分:0)

要使用简单的递归算法,请为每个递归提供到目前为止的排列(变量perm),以及仍然可用的每个数字的出现次数(数组count)。
运行代码段以生成n=2m=4的所有唯一排列(设置:11223344)。



function permutations(n, m) {
    var perm = "", count = [];                   // start with empty permutation
    for (var i = 0; i < m; i++) count[i] = n;    // set available number for each digit = n
    permute(perm, count);                        // start recursion with "" and [n,n,n...]

    function permute(perm, count) {
        var done = true;
        for (var i = 0; i < count.length; i++) { // iterate over all digits
            if (count[i] > 0) {                  // more instances of digit i available
                var c = count.slice();           // create hard copy of count array
                --c[i];                          // decrement count of digit i
                permute(perm + (i + 1), c);      // add digit to permutation and recurse
                done = false;                    // digits left over: not the last step
            }
        }
        if (done) document.write(perm + "<BR>"); // no digits left: complete permutation
    }
}

permutations(2, 4);
&#13;
&#13;
&#13;