You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现数组列表全排列并生成二维double矩阵

生成数组列表的笛卡尔积并转为二维double数组

需求回顾

给定一个包含多个double数组的列表,需要生成所有可能的元素组合(笛卡尔积),最终输出一个二维double数组,其中行数为所有数组长度的乘积,列数为列表中的数组数量。

比如输入:

List<double[]> myArray = new List<double[]> 
{ 
  new double[] { 1.2, 1.3, 1.4}, 
  new double[] { 2.1, 2.2 }, 
  new double[] { 3.1 } 
};

预期输出是6×3的二维数组:

{
  { 1.2, 2.1, 3.1 },
  { 1.2, 2.2, 3.1 },
  { 1.3, 2.1, 3.1 },
  { 1.3, 2.2, 3.1 },
  { 1.4, 2.1, 3.1 },
  { 1.4, 2.2, 3.1 }
}

现有代码的问题

你提供的递归方法Permutations2返回的是IEnumerable<IEnumerable<double>>,无法直接得到二维数组;且递归实现会产生大量临时对象(比如每次创建List<double>和调用Concat),在数据量较大时效率偏低。


解决方案1:将现有递归结果转为二维数组

如果暂时不想修改递归逻辑,可以通过LINQ将返回的枚举序列直接转为二维数组:

// 调用现有方法并转换
double[][] result = Permutations2(myArray, 0)
    .Select(combination => combination.ToArray())
    .ToArray();

但这种方式依然存在递归带来的效率问题,仅适合小体量数据场景。


解决方案2:高效非递归实现(推荐)

直接通过数组操作生成笛卡尔积,避免递归和不必要的内存开销,效率更高:

public static double[][] GenerateCartesianProduct(List<double[]> arrays)
{
    if (arrays == null || arrays.Count == 0)
        return Array.Empty<double[]>();

    // 计算总组合数:所有数组长度的乘积
    int totalCombinations = 1;
    foreach (var arr in arrays)
    {
        totalCombinations *= arr.Length;
    }

    int columnCount = arrays.Count;
    double[][] result = new double[totalCombinations][];

    // 初始化每个组合的数组
    for (int i = 0; i < totalCombinations; i++)
    {
        result[i] = new double[columnCount];
    }

    int repeatTimes = totalCombinations;
    for (int col = 0; col < columnCount; col++)
    {
        var currentArr = arrays[col];
        int elementCount = currentArr.Length;
        repeatTimes /= elementCount;

        // 按规律填充当前列的所有元素
        for (int row = 0; row < totalCombinations; row++)
        {
            int elementIndex = (row / repeatTimes) % elementCount;
            result[row][col] = currentArr[elementIndex];
        }
    }

    return result;
}

代码原理

  1. 先计算总组合数,提前分配好二维数组的内存;
  2. 对每一列,计算当前列元素的重复次数,通过数学规律直接定位每个位置应该填充的元素,避免递归调用和临时对象的创建。

使用示例

List<double[]> myArray = new List<double[]> 
{ 
    new double[] { 1.2, 1.3, 1.4}, 
    new double[] { 2.1, 2.2 }, 
    new double[] { 3.1 } 
};

double[][] product = GenerateCartesianProduct(myArray);

// 输出验证
foreach (var combo in product)
{
    Console.WriteLine($"{{ {string.Join(", ", combo)} }}");
}

内容的提问来源于stack exchange,提问作者user129994

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:30:28