11

重複の可能性:
文字列/整数のすべての順列を一覧表示

例えば、

aaa .. aaz .. aba .. abz .. aca .. acz .. azz .. baa .. baz .. bba .. bbz .. zzz

基本的に、バイナリを数えることを想像してくださいが、0から1になる代わりに、aからzになります。

私はこれを無駄にしようとしてきましたが、式はかなり複雑になっています。もっと簡単な方法があるかどうかはわかりません。

編集

私は現在このようなものを持っていますが、それは完全にはなく、より良い方法があるかどうかはわかりません:

private IEnumerable<string> GetWordsOfLength(int length)
{
    char letterA = 'a', letterZ = 'z';

    StringBuilder currentLetters = new StringBuilder(new string(letterA, length));
    StringBuilder endingLetters = new StringBuilder(new string(letterZ, length));

    int currentIndex = length - 1;

    while (currentLetters.ToString() != endingLetters.ToString())
    {
        yield return currentLetters.ToString();

        for (int i = length - 1; i > 0; i--)
        {
            if (currentLetters[i] == letterZ)
            {
                for (int j = i; j < length; j++)
                {
                    currentLetters[j] = letterA;
                }

                if (currentLetters[i - 1] != letterZ)
                {
                    currentLetters[i - 1]++;
                }
            }
            else
            {
                currentLetters[i]++;

                break;
            }
        }
    }
}
4

4 に答える 4

33

文字の組み合わせの量が可変の場合、次の操作を実行できます。

var alphabet = "abcdefghijklmnopqrstuvwxyz";
var q = alphabet.Select(x => x.ToString());
int size = 4;
for (int i = 0; i < size - 1; i++)
    q = q.SelectMany(x => alphabet, (x, y) => x + y);

foreach (var item in q)
    Console.WriteLine(item);
于 2012-12-15T10:22:19.683 に答える
14
var alphabet = "abcdefghijklmnopqrstuvwxyz";
//or var alphabet = Enumerable.Range('a', 'z' - 'a' + 1).Select(i => (char)i);

var query = from a in alphabet
            from b in alphabet
            from c in alphabet
            select "" + a + b + c;

foreach (var item in query)
{
    Console.WriteLine(item);
}

_ _EDIT_ _

一般的な解決策については、ここでCartesianProductを使用できます

int N = 4;
var result = Enumerable.Range(0, N).Select(_ => alphabet).CartesianProduct();
foreach (var item in result)
{
    Console.WriteLine(String.Join("",item));
}

// Eric Lippert’s Blog
// Computing a Cartesian Product with LINQ
// http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    // base case: 
    IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
    foreach (var sequence in sequences)
    {
        var s = sequence; // don't close over the loop variable 
        // recursive case: use SelectMany to build the new product out of the old one 
        result =
            from seq in result
            from item in s
            select seq.Concat(new[] { item });
    }
    return result;
}
于 2012-12-15T09:59:52.190 に答える
4

3つの「数字」に対して26^3のカウントがあります。3つのループで「a」から「z」まで繰り返すだけです。

于 2012-12-15T10:00:15.277 に答える
4

非常に簡単な解決策は次のとおりです。

for(char first = 'a'; first <= (int)'z'; first++)
    for(char second = 'a'; second <= (int)'z'; second++)
        for(char third = 'a'; third <= (int)'z'; third++)
            Console.WriteLine(first.ToString() + second + third);
于 2012-12-15T10:08:03.480 に答える