【问题标题】:How to get all possible combinations from an array?如何从数组中获取所有可能的组合?
【发布时间】:2015-12-31 04:02:13
【问题描述】:

我有一个类型数组,我想为这些类型生成所有可能的组合。即:(假设只有 int、bool 和 string)

int / 布尔 / 细绳 / 整数,布尔 / 整数,字符串 / 整数、布尔值、字符串 / 整数、字符串、布尔 / 等等

我在这里看到了 Eric Lippert 的回答:Generating all Possible Combinations 并且正在使用他的方法,但我很难修改它以使用类型数组而不是字符串/整数。 让我绊倒的部分是最后一部分的“Enumerable.Range()”和函数 lamba。

这是我尝试过的,但没有编译,因为 x 是 int 而不是类型。

return from cpLine in CartesianProduct(
       from type in types select Enumerable.Range(1, types.Length))
       select cpLine.Zip(types, (x1, x2) => new Tuple<Type, Type>(x1, x2));

【问题讨论】:

  • @ErikPhilips 虽然链接的问题有助于解决这个问题,但似乎问题不是重复的,因为链接的问题要求计算 2 个数组的笛卡尔积,但这个问题要求计算所有可能的排列具有可以从具有 n 个元素的数组构造的重复。结果将有 (n+n^2+n^3+...+n^n) 个元素。

标签: c# .net arrays linq ienumerable


【解决方案1】:

你可以这样使用CartesianProduct

var types = new List<Type>() { typeof(int), typeof(bool), typeof(string) };
var result = Enumerable.Range(1, types.Count())
                       .Select(x => types.AsEnumerable()).CartesianProduct().ToList();

我想你有Eric Lippert创建的CartesianProduct扩展方法:

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
        return sequences.Aggregate(
            emptyProduct,
            (accumulator, sequence) =>
                from accseq in accumulator
                from item in sequence
                select accseq.Concat(new[] { item })
            );
    }
}

这是输出:

01: Int32, Int32, Int32
02: Int32, Int32, Boolean
03: Int32, Int32, String
04: Int32, Boolean, Int32
05: Int32, Boolean, Boolean
06: Int32, Boolean, String
07: Int32, String, Int32
08: Int32, String, Boolean
09: Int32, String, String
10: Boolean, Int32, Int32
11: Boolean, Int32, Boolean
12: Boolean, Int32, String
13: Boolean, Boolean, Int32
14: Boolean, Boolean, Boolean
15: Boolean, Boolean, String
16: Boolean, String, Int32
17: Boolean, String, Boolean
18: Boolean, String, String
19: String, Int32, Int32
20: String, Int32, Boolean
21: String, Int32, String
22: String, Boolean, Int32
23: String, Boolean, Boolean
24: String, Boolean, String
25: String, String, Int32
26: String, String, Boolean
27: String, String, String

编辑


要从IEnumerable&lt;T&gt; 中获取所有可能的项目计数的所有可能输出,您可以添加此扩展方法:

public static IEnumerable<IEnumerable<T>> GetAllPossibleCombinations<T>(this IEnumerable<T> source)
{
    var result = new List<IEnumerable<T>>().AsEnumerable();
    for (int i = 1; i <= source.Count(); i++)
    {
        var intermediateResult = Enumerable.Range(1, i)
                .Select(x => source.AsEnumerable()).CartesianProduct();
        result = result.Union(intermediateResult);
    }
    return result;
}

然后这样使用:

var types = new List<Type>() { typeof(int), typeof(bool), typeof(string) };
var result = types.GetAllPossibleCombinations();

这是输出:

01: Int32
02: Boolean
03: String
04: Int32, Int32
05: Int32, Boolean
06: Int32, String
07: Boolean, Int32
08: Boolean, Boolean
09: Boolean, String
10: String, Int32
11: String, Boolean
12: String, String
13: Int32, Int32, Int32
14: Int32, Int32, Boolean
15: Int32, Int32, String
16: Int32, Boolean, Int32
17: Int32, Boolean, Boolean
18: Int32, Boolean, String
19: Int32, String, Int32
20: Int32, String, Boolean
21: Int32, String, String
22: Boolean, Int32, Int32
23: Boolean, Int32, Boolean
24: Boolean, Int32, String
25: Boolean, Boolean, Int32
26: Boolean, Boolean, Boolean
27: Boolean, Boolean, String
28: Boolean, String, Int32
29: Boolean, String, Boolean
30: Boolean, String, String
31: String, Int32, Int32
32: String, Int32, Boolean
33: String, Int32, String
34: String, Boolean, Int32
35: String, Boolean, Boolean
36: String, Boolean, String
37: String, String, Int32
38: String, String, Boolean
39: String, String, String

【讨论】:

  • 非常感谢!您使用它的方式似乎与 Eric 的方式不同。我将不得不更加努力地学习以了解它是如何工作的。谢谢。
  • 不客气,区别就在这里:在 Eric 的示例中,他使用了 2 个数组(基于提出的问题),但在这里我动态创建了一个 IEnumerable&lt;IEnumerable&lt;Type&gt;&gt;
  • 哦,实际上我注意到输出不会生成单双组合。我该怎么做?
猜你喜欢
  • 2019-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
相关资源
最近更新 更多