利用LINQ生成多种组合
给定两个整数数组,Array1和Array2,我们希望通过将第一个数组中的元素与第二个数组中的对应元素压缩来创建第一个数组中所有元素的可能组合。例如,给定:
我们希望生成以下组合:
<code> a1 b1 c1 a1 b1 c2 a1 b1 c3 a1 b1 c4 a1 b2 c1 a1 b2 c2 a1 b2 c3 a1 b2 c4 a2 b1 c1 a2 b1 c2 a2 b1 c3 a2 b1 c4 a2 b2 c1 a2 b2 c2 a2 b2 c3 a2 b2 c4 a3 b1 c1 a3 b1 c2 a3 b1 c3 a3 b1 c4 a3 b2 c1 a3 b2 c2 a3 b2 c3 a3 b2 c4 (最后一行)</code>
此过程需要我们获取表示这两个数组的序列的笛卡尔积。LINQ提供了一种生成此笛卡尔积的直接方法:
创建笛卡尔积
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 }) ); }
此方法获取序列的序列,并使用Aggregate运算符累积笛卡尔积。它以空序列作为累加器开始,并重复地将它与输入序列中的每个序列组合。对于每个组合,它将累加器中的元素与当前序列中的元素压缩以生成笛卡尔积。
压缩数据
一旦我们有了笛卡尔积,我们就可以将第一个数组中的元素与第二个数组的笛卡尔积中的对应元素压缩:
var arr1 = new[] { "a", "b", "c" }; var arr2 = new[] { 3, 2, 4 }; var result = from cpLine in CartesianProduct( from count in arr2 select Enumerable.Range(1, count)) select cpLine.Zip(arr1, (x1, x2) => x2 + x1);
CartesianProduct方法允许我们轻松地生成多个序列的笛卡尔积。我们通过为第二个数组中的每个元素生成整数范围来创建一个序列的序列,然后我们将这些范围的笛卡尔积与第一个数组压缩以创建所需的组合。
最后,我们可以遍历生成的序列的序列,并打印每一行:
foreach (var line in result) { foreach (var s in line) Console.Write(s); Console.WriteLine(); }
这段代码将生成组合作为字符串,并将其打印到控制台。
以上是如何使用Linq的笛卡尔产品生成数组元素的所有可能组合?的详细内容。更多信息请关注PHP中文网其他相关文章!