2013-05-19 10 views
6

Ich habe double[,] Array;. Ist es möglich, etwas wie double[] ColumnArray0 = Array[0,].toArray() und double[] RowArray1 = Array[,1].toArray() ohne eine Kopie von jedem elemet (mit für) zu bekommen?Wie erhält man 1D-Spalten-Array und 1D-Zeilen-Array von 2D-Array? (C# .NET)

Danke.

+0

Ich bekomme Ihre Frage nicht, aber warum sollten Sie das trotzdem tun? –

+0

Ich versuche, FFT auf Bild (2D-Array) zu implementieren, und es wird von 1D FFT implementiert, die Zeilen und dann auf Spalten aufrufen. Es wäre schön, keine unnötigen Arrays oder Zyklen zu machen.(FFT ist zeit- und speicherintensiv) –

+1

Ich denke, Sie sollten keine Bildverarbeitungsalgorithmen selbst implementieren, suchen Sie nach FFT für Bilder in C# und Sie werden feststellen, dass die Leute es bereits gemacht haben. es könnte für OpenCV für C# implementiert werden oder wenn es nicht für einen Produktionszweck ist, einfach bei Matlab oder so ähnlich bleiben –

Antwort

2

Arrays sind ein Speicherbereich, in dem alle Einträge fortlaufend gespeichert werden. Abhängig vom Datenlayout im Speicher ist dies nur für Zeilen oder Spalten möglich.

Anstelle des 2D-Arrays double[,] Typ es in Ihrem Fall ist besser ein Array von Arrays double[][]

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

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

Je nachdem, wie Sie die Daten im Array setzen zu verwenden, können Sie auch die Array2d als behandeln Spaltenarray. Aber beides gleichzeitig zu haben ist nicht möglich.

haben Sie auch einen Blick hier: Multidimensional Array [][] vs [,]

+11

Also gibt es keine Möglichkeit, dies zu tun, wenn das Array mit '[,]' definiert ist? – AdamMc331

3

Obwohl sehr spät zu sein, ich eine alternative Antwort auf die Frage zur Verfügung stellen möchten.

Der erste wichtige Teil der Frage war, auf vollständige Zeilen ODER Spalten der Matrix zugreifen zu können. Eine Möglichkeit, dies zu tun, ist die Verwendung von Erweiterungsmethoden:

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

Anwendungsbeispiel:

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. 

Der erste, was zu beachten ist, dass Sie diese generischen Methoden mit jeder Art von verwenden können, [,] - Matrizen und entsprechende [] -Vektoren. Stellen Sie sich vor, Sie würden die T s durch double ersetzen, und Sie würden die spezifische Version für "doppelt" bekommen (wie vom OP gefordert).

Die zweite Sache ist, dass das Abrufen und Setzen der Zeilen Array.Copy verwendet, während das Abrufen und Einstellen der Spalten eine Schleife verwendet. Dies liegt an der Row-Major order von C#, die die erste, aber nicht die zweite erlaubt. Natürlich können beide, wie auskommentiert, mit einer Schleife implementiert werden.

Stellen Sie sicher, dass die richtigen Bemaßungen für die set-Methoden übergeben werden oder dass das Programm abstürzt (die Fehler- und Bemaßungsüberprüfung kann einfach hinzugefügt werden). Die gesamte Logik könnte auch für gezackte Arrays wie double[][] implementiert werden, jedoch fordert das OP spezifisch nach mehrdimensionalen Arrays.

Wie für den zweiten Teil der Frage: Wenn Ihre Matrix aus Double besteht, und da Double ein Werttyp ist, werden die Werte immer kopiert. Ihr gewünschtes Verhalten, die Werte nicht zu kopieren, wäre nicht möglich. Wenn Sie jedoch Objekte wie T verwenden, wird nur die Referenz kopiert, die auf das Objekt zeigt, und nicht das Objekt selbst (achten Sie also darauf, das "kopierte" Objekt zu mutieren).

Schließlich, wenn Sie wirklich nicht wollen, die Doppel-Werte zu kopieren, würde ich vorschlagen, Ihre ganze Matrix übergeben (nur die Referenz wird übergeben), und dann direkt durch die gewünschten Spalten und/oder Zeilen.

Verwandte Themen