简体   繁体   English

C#中的组合算法

[英]Combination Algorithm in C#

I need a combination of n fields where each field can be equal to null or not null. 我需要n个字段的组合,其中每个字段可以等于null或不为null。 For each combination, the fields cannot be repeated. 对于每个组合,不能重复这些字段。 Basically, there should be a total of 2^n combinations. 基本上,应该总共有2 ^ n种组合。

Example: 例:

if I have 2 fields A and B , the combinations in the output should be: 如果我有2个字段AB ,则输出中的组合应为:

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

if I have 3 fields A, B, and C, the combinations in the output should be: 如果我有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

I don't know what this combination is called, so how can I do this in code where the number of fields is a variable? 我不知道这个组合被调用了什么,所以如何在代码中执行此操作,其中字段数是变量?

Thanks! 谢谢!

If you want a generator of such lines you can use Linq : 如果你想要这样的生成器 ,你可以使用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));

For count = 2 the output is 对于count = 2 ,输出为

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

Edit: A small modification lets you put your own names: 编辑:一个小修改可以让你自己的名字:

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

I usually stick to simple recursion in cases like this, because it's so easy to understand. 在这种情况下,我通常坚持简单的递归,因为它很容易理解。 No explanation, I'll just let the (untested) code talk for itself: 没有解释,我只是让(未经测试的)代码自己说话:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM