C#中的数组列表排列

huangapple go评论60阅读模式
英文:

Permutation of list of arrays C#

问题

I have a list of arrays and I would like to generate all possible permutations and save the output in a 2D double matrix.

Let's assume the list of array is given by

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

The expected output is a 2D double array of size 6 x 3. 6 comes from the product of the lengths of all arrays in the list, and 3 is the number of arrays in the list. The elements have the form

{
  { 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 }
}

I have tried the following piece of code

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);
        }    
    }
}

But the output is not a 2D array and it uses recursion, which is not efficient.

英文:

I have a list of arrays and I would like to generate all possible permutations and save the output in a 2D double matrix.

Let's assume the list of array is given by

List&lt;double[]&gt; myArray = new List&lt;double[]&gt; 
{ 
  new double[] { 1.2, 1.3, 1.4}, 
  new double[] { 2.1, 2.2 }, 
  new double[] { 3.1 } 
};

The expected output is a 2D double array of size 6 x 3. 6 comes from the product of length all arrays in the list and 3 is the number of arrays in the list. The element of it has the form

{
  { 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 }
}

I have tried the following piece of code

public static IEnumerable&lt;IEnumerable&lt;double&gt;&gt; Permutations2(List&lt;double[]&gt; array, int column)
{
    if (column == array.Count)
    {
        yield return Enumerable.Empty&lt;double&gt;();
        yield break;
    };

    for (int j = 0; j &lt; array[column].GetLength(0); j++)
    {
        double v = array[column][j];
        var first = new List&lt;double&gt; { v };
        foreach (var combination in Permutations2(array, column + 1))
        {
            yield return first.Concat(combination);
        }    
    }
}

But the output is not a 2D array and it uses recursion which is not efficient.

答案1

得分: 0

你可以使用嵌套循环来生成所有可能的组合。以下是一种实现方法:

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();

这段代码首先计算了结果矩阵中所需的行数。然后,它使用正确的维度初始化了一个2D双精度数组。索引数组用于跟踪myArray中每个数组的当前索引。

外部循环生成结果矩阵中的每一行。内部循环设置了当前行中每一列的值。在设置最后一列的值后,索引数组会被更新。如果某一列的索引达到其对应数组的末尾,它会被重置为0,并且前一列的索引会递增。

这种方法避免了递归,能够在单次遍历中生成所有组合。

英文:

You can use a nested loop to generate all possible combinations. Here's one way to do it:

 List&lt;double[]&gt; myArray = new List&lt;double[]&gt; { 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 &lt; rows; i++) {
        for (int j = 0; j &lt; myArray.Count; j++) {
          result[i, j] = myArray[j][index[j]];
        }

        for (int j = myArray.Count - 1; j &gt;= 0; j--) {
          index[j]++;

          if (index[j] &lt; myArray[j].Length) {
            break;
          }

          index[j] = 0;
        }
      }
      for (int i = 0; i &lt; rows; i++) {
        for (int j = 0; j &lt; myArray.Count; j++) {
          Console.Write(result[i, j]);
          Console.Write(&quot;;&quot;);
        }
        Console.Write(&quot;\n&quot;);
      }
      Console.ReadKey();

The code first calculates the number of rows needed in the result matrix. It then initializes a 2D double array with the correct dimensions. The index array keeps track of the current index for each array in myArray.

The outer loop generates each row in the result matrix. The inner loop sets the value of each column in the current row. After setting the value for the last column, the index array is updated. If the index for a column reaches the end of its corresponding array, it is reset to 0 and the index for the previous column is incremented.

This approach avoids recursion and generates all combinations in a single pass.

huangapple
  • 本文由 发表于 2023年3月31日 21:40:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定