如何将未知数量的int数组合并为含所有取值组合的数组数组?
实现任意数量int数组的笛卡尔积组合
这个问题本质上是求多个集合的笛卡尔积,正好可以用递归或者LINQ的聚合操作来实现,完全适配数组数量未知的场景。下面给你两种实用的实现方式:
方法一:递归实现(直观易理解)
递归的思路是逐步构建每个组合:从第一个数组开始,依次遍历每个元素,将其加入当前组合,然后递归处理下一个数组;当处理完所有数组时,就得到一个完整的组合,将其存入结果集合。
public static class ArrayCombiner { // 公共调用方法 public static int[][] CombineArrays(params int[][] arrays) { // 预处理:过滤空数组,避免空引用异常 var validArrays = arrays?.Where(arr => arr != null && arr.Length > 0).ToArray() ?? Array.Empty<int[]>(); if (validArrays.Length == 0) return Array.Empty<int[]>(); var result = new List<int[]>(); CombineRecursive(validArrays, 0, new List<int>(), result); return result.ToArray(); } // 递归核心逻辑 private static void CombineRecursive(int[][] arrays, int currentIndex, List<int> currentCombination, List<int[]> result) { // 递归终止条件:处理完所有数组,保存当前组合 if (currentIndex == arrays.Length) { result.Add(currentCombination.ToArray()); return; } // 遍历当前数组的所有元素,逐个加入组合并递归处理下一个数组 foreach (int num in arrays[currentIndex]) { currentCombination.Add(num); CombineRecursive(arrays, currentIndex + 1, currentCombination, result); // 回溯:移除最后加入的元素,准备尝试当前数组的下一个元素 currentCombination.RemoveAt(currentCombination.Count - 1); } } }
用法示例
var array1 = new[] {0, 2, 4, 6}; var array2 = new[] {0, 4, 5, 7}; var array3 = new[] {1, 4, 3, 5}; // 生成所有组合 int[][] resultingArray = ArrayCombiner.CombineArrays(array1, array2, array3); // 打印结果(可选) foreach (var combo in resultingArray) { Console.WriteLine($"[{string.Join(", ", combo)}]"); }
方法二:LINQ聚合实现(简洁优雅)
利用LINQ的Aggregate方法,从一个包含空数组的集合开始,逐步将每个后续数组的元素与已有的所有组合拼接,最终得到完整的笛卡尔积。
public static class ArrayCombiner { public static int[][] CombineArrays(params int[][] arrays) { var validArrays = arrays?.Where(arr => arr != null && arr.Length > 0).ToArray() ?? Array.Empty<int[]>(); if (validArrays.Length == 0) return Array.Empty<int[]>(); // 从空数组开始,逐步聚合每个数组的元素 return validArrays.Aggregate( (IEnumerable<int[]>)new[] { Array.Empty<int>() }, (accumulatedCombos, currentArray) => accumulatedCombos.SelectMany(combo => currentArray.Select(num => combo.Concat(new[] { num }).ToArray())) ).ToArray(); } }
逻辑说明
- 初始值
new[] { Array.Empty<int>() }是一个包含空数组的集合,作为组合的起点; Aggregate的每一步,都会把已有的所有组合(accumulatedCombos)和当前数组的每个元素拼接,生成新的组合集合;- 最终将聚合结果转为数组,就是所有可能的组合。
两种方法都能实现你的需求:递归方式更直观,适合调试和理解;LINQ方式代码更简洁,适合追求代码紧凑的场景。
内容的提问来源于stack exchange,提问作者Azimuth
相关产品推荐
相关产品推荐

