Комбинированный алгоритм в C #

Обновить

December 2018

Просмотры

148 раз

1

Мне нужно сочетание п полей , где каждое поле может быть равно нулю или не равно нулю. Для каждой комбинации полей не могут повторяться. В принципе, не должно быть в общей сложности 2 ^ п комбинаций.

Пример:

если у меня есть 2 поля Aи B, в комбинации на выходе должно быть:

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

если у меня есть 3 поля А, В, и С, в комбинации выходе должно быть:

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

Я не знаю, что называется эта комбинация, так как я могу сделать это в коде, где число полей переменной?

Спасибо!

2 ответы

0

Я обычно придерживаться простой рекурсии в подобных случаях, потому что это так легко понять. Никаких объяснений, я не буду просто позволить (непроверенные) код говорить для себя:

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

Если вы хотите генератор таких линий можно использовать 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

Edit: Небольшая модификация позволяет поместить свои собственные имена:

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