13

私は持っていdouble[,] Array;ます。すべての要素のコピーを作成せずに (for を使用して) double[] ColumnArray0 = Array[0,].toArray()andのようなものを取得することは可能ですか?double[] RowArray1 = Array[,1].toArray()

ありがとう。

4

2 に答える 2

14

非常に遅くなりましたが、質問に対する別の回答を提供したいと思います。

質問の最初の重要な部分は、行列の行または列全体にアクセスできるようにすることでした。これを行う 1 つの可能性は、拡張メソッドを使用することです。

public static class MatrixExtensions
{
  /// <summary>
  /// Returns the row with number 'row' of this matrix as a 1D-Array.
  /// </summary>
  public static T[] GetRow<T>(this T[,] matrix, int row)
  {
    var rowLength = matrix.GetLength(1);
    var rowVector = new T[rowLength];

    for (var i = 0; i < rowLength; i++)
      rowVector[i] = matrix[row, i];

    return rowVector;
  }



  /// <summary>
  /// Sets the row with number 'row' of this 2D-matrix to the parameter 'rowVector'.
  /// </summary>
  public static void SetRow<T>(this T[,] matrix, int row, T[] rowVector)
  {
    var rowLength = matrix.GetLength(1);

    for (var i = 0; i < rowLength; i++)
      matrix[row, i] = rowVector[i];
  }



  /// <summary>
  /// Returns the column with number 'col' of this matrix as a 1D-Array.
  /// </summary>
  public static T[] GetCol<T>(this T[,] matrix, int col)
  {
    var colLength = matrix.GetLength(0);
    var colVector = new T[colLength];

    for (var i = 0; i < colLength; i++)
      colVector[i] = matrix[i, col];

    return colVector;
  }



  /// <summary>
  /// Sets the column with number 'col' of this 2D-matrix to the parameter 'colVector'.
  /// </summary>
  public static void SetCol<T>(this T[,] matrix, int col, T[] colVector)
  {
    var colLength = matrix.GetLength(0);

    for (var i = 0; i < colLength; i++)
      matrix[i, col] = colVector[i];
  }
}

使用例:

double[,] myMatrix = ... // Initialize with desired size and values.
double[] myRowVector = myMatrix.GetRow(2); // Gets the third row.
double[] myColVector = myMatrix.GetCol(1); // Gets the second column.
myMatrix.SetCol(2, myColVector); // Sets the third column to the second column.

最初に注意すべきことは、これらのジェネリック メソッドを任意の種類の [,]-行列と対応する []-ベクトルで使用できることです。Ts をs に置き換えると想像してdoubleください。そうすれば、「double」の特定のバージョンが得られます (OP から要求されたとおり)。

2 つ目は、行の取得と設定には が使用Array.Copyされ、列の取得と設定にはループが使用されることです。これは、C#の行優先順によるもので、最初は許可されますが、2 番目は許可されません。もちろん、コメントアウトされているように、どちらもループで実装できます。

set-Methods に正しい次元を渡してください。そうしないと、プログラムがクラッシュします (エラーと次元のチェックを簡単に追加できます)。のようなギザギザの配列に対してロジック全体を実装することもできますがdouble[][]、OPは特に多次元のものを要求しました。

質問の 2 番目の部分について: マトリックスが double で構成されていて、double が値型であるため、値は常にコピーされます。したがって、値をコピーしないという望ましい動作は不可能です。ただし、オブジェクトを as として使用する場合Tは、オブジェクト自体ではなく、オブジェクトを指す参照のみがコピーされます (「コピーされた」オブジェクトの変更に注意してください)。

最後に、二重値を本当にコピーしたくない場合は、マトリックス全体を渡し (参照のみが渡される)、目的の列や行を直接ループすることをお勧めします。

于 2016-08-09T09:11:41.513 に答える
6

配列は、すべてのエントリが連続して格納されるメモリ領域です。メモリ内のデータ レイアウトに応じて、これは行または列のいずれかでのみ可能です。

2次元配列タイプの代わりに、double[,]配列の配列を使用する方が良い場合がありますdouble[][]

double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...

and then:
double[] RowArray0 = Array2d[0];

配列にデータを配置する方法によっては、 を列配列として扱うこともできますArray2d。しかし、両方を同時に持つことは不可能です。

こちらもご覧ください: 多次元配列 [][] vs [,]

于 2013-05-19T15:55:39.737 に答える