5

与えられた長さで k の順列を見つけるにはどうすればよいですか?

例えば:

単語catには 3 文字あります: 単語内の 2 の順列をすべて見つけるにはどうすればよいでしょうかcat。結果は次のようになります: ac, at, ca,acなど...


これは宿題の問題ではありません。任意の言語を使用できますが、C/C++ または C# の方が望ましいです。サイズ LENGTH の再帰を作成する方法は知っていますが、カスタム サイズについては知りません。

4

6 に答える 6

3

これは C# のもので、文字が繰り返されても機能するはずです。たとえば、長さ 2 の順列の「バナナ」では、次のようになります。

ba bn ab aa an nb na nn

基本的な考え方は、最初の文字を修正してから、長さ k-1 のすべての順列を形成し、それらの k-1 の長さの順列の先頭に文字を追加することです。重複する文字を処理するために、残りの数 (つまり、サブ順列に使用できるもの) を追跡します。

模範的なコードではありませんが、アイデアが得られるはずです。(バグを見つけた場合はお知らせください。編集できます)。

static List<string> Permutations(Dictionary<char, int> input, int length) {
    List<string> permutations = new List<string>();

    List<char> chars = new List<char>(input.Keys);

    // Base case.
    if (length == 0) {
        permutations.Add(string.Empty);
        return permutations;
    }

    foreach (char c in chars) {

        // There are instances of this character left to use.
        if (input[c] > 0) {

            // Use one instance up.
            input[c]--;

            // Find sub-permutations of length length -1.
            List<string> subpermutations = Permutations(input, length - 1);

            // Give back the instance.
            input[c]++;

            foreach (string s in subpermutations) {

                // Prepend the character to be the first character.
                permutations.Add(s.Insert(0,new string(c,1)));

            }
        }
    }

    return permutations;
}

そして、これを使用するための完全なプログラムを次に示します。

using System;
using System.Collections.Generic;

namespace StackOverflow {

    class Program {
        static void Main(string[] args) {
            List<string> p = Permutations("abracadabra", 3);
            foreach (string s in p) {
                Console.WriteLine(s);
            }
        }

        static List<string> Permutations(string s, int length) {
            Dictionary<char, int> input = new Dictionary<char, int>();
            foreach (char c in s) {
                if (input.ContainsKey(c)) {
                    input[c]++;
                } else {
                    input[c] = 1;
                }
            }
            return Permutations(input, length);
        }

        static List<string> Permutations(Dictionary<char, int> input, 
                                                          int length) {
            List<string> permutations = new List<string>();

            List<char> chars = new List<char>(input.Keys);
            if (length == 0) {
                permutations.Add(string.Empty);
                return permutations;
            }

            foreach (char c in chars) {
                if (input[c] > 0) {
                    input[c]--;
                    List<string> subpermutations = Permutations(input, 
                                                                length - 1);
                    input[c]++;

                    foreach (string s in subpermutations) {
                        permutations.Add(s.Insert(0,new string(c,1)));
                    }
                }
            }

            return permutations;
        }
    }
}
于 2010-02-28T07:21:52.190 に答える
1

再帰的なソリューションと追加のパラメーター (深さ) を渡して、再帰関数が深さ > n に対してすぐに戻るようにすることの何が問題になっていますか。

于 2010-02-28T06:16:09.903 に答える
1
void Prem (char *str, int k, int length) {
    if (k == length-1){
         printf("%s\n",str);
         return;
    } else {
        for (int i = k ; i < length; ++i) {
            char t = str[k];
            str[k] = str[i];
            str[i] = t;
            Prem(str,k+1,length);
            t = str[k];
            str[k] = str[i];
            str[i] = t;
        }
    }
}
于 2010-09-01T18:36:48.987 に答える
1

最も効率的ではありませんが、機能します:

public class permutation
{
    public static List<string> getPermutations(int n, string word)
    {
        List<string> tmpPermutation = new List<string>();
        if (string.IsNullOrEmpty(word) || n <= 0)
        {
            tmpPermutation.Add("");
        }
        else
        {
            for (int i = 0; i < word.Length; i++)
            {
                string tmpWord = word.Remove(i, 1);
                foreach (var item in getPermutations(n - 1, tmpWord))
                {
                    tmpPermutation.Add(word[i] + item);
                }
            }
        }
        return tmpPermutation;
    }
}
于 2010-02-28T07:12:33.727 に答える