我在 C# 中有一个数组列表,我想生成所有可能的排列并将输出保存在二维双矩阵中。
让我们假设数组列表由
给出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 x 3 的二维双精度数组。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}}
我试过下面的一段代码
public static IEnumerable<IEnumerable<double>> Permutations2 (List<double[]> array, int column)
{
if (column == array.Count)
{
yield return Enumerable.Empty<double>();
yield break;
};
for (int j = 0; j < array[column].GetLength(0); j++)
{
double v = array[column][j];
var first = new List<double> { v };
foreach (var combination in Permutations2(array, column + 1))
{
yield return first.Concat(combination);
}
}
}
但输出不是二维数组,它使用效率不高的递归。
谢谢
您可以使用嵌套循环来生成所有可能的组合。这是一种方法:
List<double[]> myArray = new List<double[]> { new double[] { 1.2, 1.3, 1.4 }, new double[] { 2.1, 2.2 }, new double[] { 3.1 } };
int rows = 1;
foreach (double[] arr in myArray) {
rows *= arr.Length;
}
double[,] result = new double[rows, myArray.Count];
int[] index = new int[myArray.Count];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < myArray.Count; j++) {
result[i, j] = myArray[j][index[j]];
}
for (int j = myArray.Count - 1; j >= 0; j--) {
index[j]++;
if (index[j] < myArray[j].Length) {
break;
}
index[j] = 0;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < myArray.Count; j++) {
Console.Write(result[i, j]);
Console.Write(";");
}
Console.Write("\n");
}
Console.ReadKey();
代码首先计算结果矩阵中需要的行数。然后它用正确的尺寸初始化一个二维双精度数组。索引数组跟踪 myArray 中每个数组的当前索引。
外循环生成结果矩阵中的每一行。内部循环设置当前行中每一列的值。为最后一列设置值后,索引数组被更新。如果列的索引到达其对应数组的末尾,则将其重置为 0,并递增前一列的索引。
这种方法避免了递归并在一次通过中生成所有组合。