C# 中的组合算法

本文关键字:算法 组合 | 更新日期: 2023-09-27 18:36:58

我需要n个字段的组合,其中每个字段可以等于null或不null。对于每个组合,字段不能重复。基本上,总共应该有 2^n 种组合。

例:

如果我有 2 个字段AB,输出中的组合应该是:

A != null and B != null
A != null and B == null
A == null and B != null
A == null and B == null

如果我有 3 个字段 A、B 和 C,则输出中的组合应该是:

A != null and B != null and C != null
A != null and B != null and C == null
A != null and B == null and C != null
A != null and B == null and C == null
A == null and B != null and C != null
A == null and B != null and C == null
A == null and B == null and C != null
A == null and B == null and C == null

我不知道这种组合叫什么,那么如何在字段数为变量的代码中执行此操作?

谢谢!

C# 中的组合算法

如果你

想要这样的行的生成器,你可以使用Linq

   int count = 2;
   var lines = Enumerable
     .Range(0, 1 << count) // 1 << count == 2 ** count
     .Select(item => String.Join(" and ", Enumerable
       .Range(0, count)
       .Select(index => ((Char) ('A' + index)).ToString() + 
                        ((item >> index) % 2 == 0 ? " != null" : " == null"))));

   // Let's print out all the lines generated
   Console.Write(String.Join(Environment.NewLine, lines));

对于count = 2,输出为

  A != null and B != null
  A == null and B != null
  A != null and B == null
  A == null and B == null

编辑:一个小的修改让你输入自己的名字:

  String[] names = new String[] { "A", "B", "C" };
  var lines = Enumerable
    .Range(0, 1 << names.Length) // 1 << count == 2 ** count
    .Select(item => String.Join(" and ", Enumerable
       .Range(0, names.Length)
       .Select(index => names[index] +
                        ((item >> index) % 2 == 0 ? " != null" : " == null"))));
  // Let's print out all the lines generated
  Console.Write(String.Join(Environment.NewLine, lines));
在这种情况下,

我通常坚持使用简单的递归,因为它很容易理解。没有解释,我只是让(未经测试的)代码自己说话:

public void Generate()
{
    Create("", 0);
}
private string[] names = new[]{ "A", "B", "C" };
public void Create(string s, int current)
{
    if (current != 0)
    { 
        s += " and ";
    }
    if (current != names.Length)
    {
        string c1 = s + names[current] + " == null"; // case 1
        string c2 = s + names[current] + " != null"; // case 2
        Create(c1, current+1);
        Create(c2, current+1);
    }
    else
    {
        Console.WriteLine(s);
    }
}