C# LINQ 组合数学:没有空集的集合的所有组合

C# LINQ combinatorics: All Combinations of a Set without the Empty Set

我有一组字符串,我想找到所有可能的字符串组合并将它们添加到列表中。我想以每个字符串组合的列表列表结束,减去空集。

我创建了一个完全使用嵌套 for 循环执行此操作的解决方案。但是我想更优雅地做到这一点,最好是使用 LINQ,但我对它不是很精通,因为我对它还是很陌生。

解决方案应该有 2^n - 1 个组合列表,其中 n 是原始集合的基数。这是我正在寻找的正确示例:

set = {a, b, c}

completedListOfCombinations = 
{
    {a},
    {b},
    {a, b},
    {c},
    {a, c},
    {b, c},
    {a, b, c}
}

这是我的工作,基本但丑陋的解决方案,是我在以下人员的帮助下制作的:

List<string> myStrings =  new List<string> { "a", "b", "c" };

var allCombos = new List<List<string>>();

for (int i = 0; i < myStrings.Count; i++)
{
    int subsetCount = allCombos.Count;
    var m = new List<string>();
    m.Add(myStrings[i]);
    allCombos.Add(m);

    for (int j = 0; j < subsetCount; j++)
    {
        string[] subset = new string[allCombos.ElementAt(j).Count + 1];
        allCombos[j].CopyTo(subset, 0);
        subset[subset.Length - 1] = myStrings[i];
        allCombos.Add(subset.ToList());
    }

}

有人可以告诉我一个更优雅的解决方案吗?我见过类似的 LINQ 解决方案,它们创建笛卡尔对和带有阈值的列表,但我无法根据需要调整它们。

假设 所有 list 中的值是 唯一的:

  List <String> list = new List<String> { "a", "b", "c" };

  var result = Enumerable
    .Range(1, (1 << list.Count) - 1)
    .Select(index => list.Where((item, idx) => ((1 << idx) & index) != 0).ToList());

打印出来:

Console.WriteLine(String
  .Join(Environment.NewLine, result
     .Select(line => String.Join(", ", line))));

结果是

a
b
a, b
c
a, c
b, c
a, b, c