【问题标题】:Listing permutations of different combination of characters列出不同字符组合的排列
【发布时间】:2023-11-17 16:44:01
【问题描述】:

我找到的最接近的 SO 主题在这里:Listing all permutations of a string/integer

但是对于字符串中每个位置的不同字符集,我该如何使用它呢?

一个例子:我指定一个字符串长度为“3”。前两个位置应该是“a”或“b”,但最后一个位置应该是“1”或“2”,例如:

aa1
ba1
ab1
bb1
aa2
ab2
ba2
bb2

【问题讨论】:

  • 三个嵌套循环呢?你有没有尝试过?
  • 可能他想要一些更通用的方法。 @filur 我会在几分钟内给你写代码并分享给你。

标签: c# algorithm combinations permutation


【解决方案1】:

使用此代码:

public static List<string> GenerateCombinations(char[][] characters)
{
    var combinations = new List<string>();
    GenerateCombinations(0, characters, new char[characters.GetLength(0)], combinations);
    return combinations;
}

private static void GenerateCombinations(int level, char[][] characters, char[] current, List<string> combinations)
{
    if (level == characters.GetLength(0))
    {
        combinations.Add(new string(current));
        return;
    }

    foreach (var character in characters[level])
    {
        current[level] = character;
        GenerateCombinations(level + 1, characters, current, combinations);
    }
}

使用示例:

public static void Main()
{
    var characters = new[]
                     {
                         new[] { 'a', 'b' },
                         new[] { 'a', 'b' },
                         new[] { '1', '2' }
                     };

    var combinations = GenerateCombinations(characters);
    foreach (var combination in combinations)
    {
        Console.WriteLine(combination);
    }
}

输出:

aa1
aa2
ab1
ab2
ba1
ba2
bb1
bb2

【讨论】:

    【解决方案2】:

    如果长度是固定的,您可以使用这个创建 cartesian product 的简单查询:

    string chars = "ab";
    int[] digits = { 1, 2 };
    var query = from c1 in chars 
                from c2 in chars 
                from d1 in digits 
                select string.Format("{0}{1}{2}", c1, c2, d1);
    string[] possibleCombinations = query.ToArray();
    

    结果:

    aa1
    aa2
    ab1
    ab2
    ba1
    ba2
    bb1
    bb2
    

    编辑:对于它的价值,按要求使用 lambda(查询语法更具可读性):

    possibleCombinations = chars
        .SelectMany(c1 => chars
            .SelectMany(c2 => digits
                .Select(d1 => string.Format("{0}{1}{2}", c1, c2, d1))))
        .ToArray();
    

    如果你需要一种处理动态长度的方法,你可以看看这个:

    Dynamic Generation of All Possible Combinations of Index of an Array

    【讨论】:

    • 谢谢。只是出于好奇,你能告诉我使用 lambda 而不是 linq 的解决方案吗?
    • @filur:我添加了方法语法。
    • FWIW,chars.SelectMany(c1 =&gt; chars, (c1, c2) =&gt; new { c1, c2 }).SelectMany(τ0 =&gt; digits, (τ0, d1) =&gt; string.Format("{0}{1}{2}", τ0.c1, τ0.c2, d1)) 是编译器将进行的稍微更好(哈哈)的 lambda 转换。
    最近更新 更多