【发布时间】:2021-02-07 05:21:37
【问题描述】:
我想写一个函数,它返回一个数组的笛卡尔积,它自身的次数是可变的。
现在,如果在编译时知道笛卡尔积的数量,那么我可以执行以下操作(对于 3 个笛卡尔积):
public static void Main(string[] args)
{
int[] numSet = {1,2,3,4};
var cartesianProduct = from letter in numSet
from number in numSet
from colour in numSet
select new { num1, num2, num3};
}
现在,我看到了这个答案:https://stackoverflow.com/a/4073806/5859885,它似乎提供了一种处理可变数量集合的方法。方法如下:
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(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 }));
}
现在,我已将其应用于我的问题,如下所示(这是针对 4 个笛卡尔积(参见 for 循环),但可以很容易地包装在用于可变数量的笛卡尔积的方法中)
static void Main(string[] args)
{
int[] numSet= new int[] { 1, 2, 3, 4};
List<int[]> numList = new List<int[]>();
for(int i=0; i<4; i++)
{
numList.Add(numSet);
}
IEnumerable<IEnumerable<int>> combArray = CartesianProduct(numList);
foreach(var combo in combArray)
{
Console.WriteLine(combo);
}
}
现在,这可以编译,但我只是为 for 循环的每次迭代(而不是笛卡尔积)获得以下输出。
System.Linq.Enumerable+ConcatNIterator'1[System.Int32].
这里发生了什么?
【问题讨论】:
-
更改写入语句:Console.WriteLine(string.Join(",",combo));
-
谢谢!你知道我如何将每个组合存储在一个数组中,然后将所有这些组合存储在一个数组中吗?所以我有一个锯齿状数组(数组数组)?
-
它们已经在变量 numList 中。它不是锯齿状的,只是一个规则的二维数组,因为宽度总是 4。
标签: c# arrays .net linq cartesian-product