如何获取所有可能的三个字母排列?

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;
            }
        }
    }
}

3
请查看此问题。 - Zbigniew
还要看一下这个问题生成字符串的所有可能排列列表 - Ortwin Angermeier
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);

我知道这很老了,但你可以使用LINQ来打印数组。q.ForEach(x => Console.WriteLine(x)); - asdfasdfadsf
1
@JasonHeddle,IEnumerable没有ForEach扩展。 - Magnus
如果你想要将其转换为数组,只需要在 .Foreach 之前添加 .ToArray() 即可,像这样:q.ToArray().ForEach(Console.WriteLine); - asdfasdfadsf
2
@JasonHeddle - ForEach 方法仅适用于 List<T>。这个 foreach 有什么问题? - Rahul Singh

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);
}

__编辑__

对于一个通用的解决方案,您可以使用这里的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;
}

我很惊讶,但是没错,这个可以运行。 - Carra
2
我想到了这样的方法,但如果我有可变数量的可能字母组合怎么办?我只是举了3个例子。可能需要4或5个。 - Ryan Peschel
@RyanPeschel 那就使用这里的CartesianProduct,并给它一个包含n个字母的字母表。 - L.B

4

您有26^3个计数器可以用于3个“数字”。只需在三个循环中从“a”到“z”进行迭代即可。


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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接