Große Matrix in kleine quadratische Matrizen einteilen



  • Hallo,

    also ich habe eine Frage und zwar geht es darum eine große Matrix wie z.B. eine 963x672 Matrix in kleine quadratische Matrizen zu unterteilen ( der Nutzer wird per Ausgabe aufgefordert wie groß die quadratische Dimension sein soll).
    Das bedeutet, sobald sich der Nutzer für eine Dimension entschieden hat, sollte das Programm von oben links in der Matrix starten und die Matrix am besten von links nach rechts in kleine quadratisch Matrizen unterteilen.
    Die erste Matrix einzuteilen, habe ich schon mal gemacht,wobei ich eine 10x10 einfach als Testmatrix benutzt habe, und halte es so auch für richtig:

    #include <iostream>
    #include <iomanip>

    using namespace std;

    int main(){

    int Wertematrix[10][10]={{1,2,3,4,5,6,7,8,9,10},
    {11,12,13,14,15,16,17,18,19,20},
    {21,22,23,24,25,26,27,28,29,30},
    {31,32,33,34,35,36,37,38,39,40},
    {41,42,43,44,45,46,47,48,49,50},
    {51,52,53,54,55,56,57,58,59,60},
    {61,62,63,64,65,66,67,68,69,70},
    {71,72,73,74,75,76,77,78,79,80},
    {81,82,83,84,85,86,87,88,89,90},
    {91,92,93,94,95,96,97,98,99,100}
    };

    // Einlesen der Matrix- bzw. Auswertefenstergröße

    int Dimension;

    cout<<"Es wird eine quadratische Pixelgröße nach dem Schema (Zeilen x Spalten) benötigt, bitte geben Sie die gewünschte Dimension für das Auswertefenster ein:"<<endl;
    cin>>Dimension; // Dimensionen einlesen

    int** Auswertefenster = new int* [Dimension]; //Erezugt Dimension integer-Pointer

    for(int i=0; i<=Dimension; i++){
    Auswertefenster[i]= new int [Dimension]; //Erzeugt Dimension x Dimension int

    }

    for(int k=0; k<=Dimension; k++){
    for(int l=0; l<=Dimension; l++){

    Auswertefenster[k][l]= Wertematrix[k][l];
    

    }
    }

    for (int k=0; k<Dimension; k++) { // Testausgabe der Matrix
    for (int l=0; l<Dimension; l++) {
    cout << setw(20) << Wertematrix[k][l];
    }
    cout << "\n";
    }

    return 0;

    }

    Also falls jemand eine Idee hätte wie man fortfahren könnte oder eine Anregung hat, fände
    ich das ganz gut :D. Ich hab mir gedacht vielleicht immer die Dimension der Wertematrix durch die gewünschte quadratische Dimension des Nutzers zu teilen, um so schon mal auf die Anzahl der Matrizen zu kommen, die man überhaupt benötigt.

    Ich bedanke mich für alle produktiven Antworten. 🙂



  • Warum kopierst du die Daten?


  • Global Moderator |  Mod

    Was meinst du genau mit "unterteilen"? Was soll das Programm tun?

    Ansonsten das übliche:

    • Benutze kein new in C++!
    • Ein Zeiger ist kein Array, ein Array ist kein Zeiger, und dementsprechend ist ein Zeiger auf einen Zeiger auch ganz etwas anderes als ein Array von Arrays.


  • Nur ein Tip, wie man vielleicht etwas strukturierter an dieses Problem herangehen kann. Zunächst mal eine kurze Veranschaulichung:

    Allgemein sieht deine grosse Matrix so aus:

    M=[a00a01a0na10a11a1nam0am1a(m1)(n1)]M = \begin{bmatrix} a_{00} & a_{01} & \cdots & a_{0n} \\ a_{10} & a_{11} & \cdots & a_{1n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m0} & a_{m1} & \cdots & a_{(m-1)(n-1)} \end{bmatrix}

    Wenn du diese in Untermatrizen unterteilst, z.B. in 3×33\times3-Matrizen sieht das so aus:

    MU=[[a00a01a02a10a11a12a20a21a22]]M_U = \begin{bmatrix} \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \\ a_{20} & a_{21} & a_{22} \end{bmatrix} & \cdots \\\\ \vdots & \ddots \end{bmatrix}

    oder allgemeiner:

    MU=[U00U01U10U11]M_U = \begin{bmatrix} U_{00} & U_{01} & \cdots \\ U_{10} & U_{11} & \cdots \\ \vdots & \vdots & \ddots \end{bmatrix}

    Wobei UijU_{ij} deine nU×nUn_U \times n_U (z.B. 3×33\times3)-Untermatrizen sind, die bei der Unterteilung entstehen.

    Ich würde zunächst einmal zwei Funktionen* schreiben, welche für jeweils die Zeilen und die Spalten die Koordinaten (ii und jj) von der Unterteilungs-Darstellung in die Koordinaten der grossen Matrix überführt. Diese könnten z.B. folgende Signaturen haben:

    int zu_m_i(int n_u, int i_u, int i);
    int zu_m_j(int n_u, int j_u, int j);
    

    Wobei der Rückgabewert der Funktionen, jeweils die ii/jj-Koordinaten in deiner grossen Matrix sind. Die Parameter haben dabei folgende Bedeutung:

    n_u: Wie gross die kleine, quadratische Matrix ist. Also 10 in deinem Beispiel, oder 3 wie bei meinem Beispiel. In deinem Code hast du diesen Wert Dimension genannt.
    i_u und j_u: Die Koordinaten der Untermatrix selbst in der unterteilten Matrix MUM_U, also z.B. 1 und 2 für die Untermatrix U12U_{12}. Mit diesen Koordinaten wird die Untermatrix indentifiziert, auf die du dich beziehst.
    i und j: Die Koordinaten innerhalb der Untermatrix.

    Willst du nun z.B. die Untermatrix in der zweiten Zeile (i_u = 1) und dritten Spalte (i_j = 2) ausgeben, könnte der Code dafür z.B. so aussehen:

    for (int i=0; i < Dimension; i++)
    {
        for (int j=0; j < Dimension; j++)
        {
            int m_i = zu_m_i(Dimension, 1, i);
            int m_j = zu_m_j(Dimension, 2, j);
            assert(m_i >= 0 && m_i < GROSSE_MATRIX_M);
            assert(m_j >= 0 && m_j < GROSSE_MATRIX_N);
            cout << setw(20) << GrosseMatrix[m_i][m_j];
        }
        cout << "\n";
    }
    

    Die Funktionen zu_m_i() und zu_m_j() zu schreiben ist nicht besonders schwer, und in dieser Form ist dein Problem auch einfacher zu handhaben, wie ich finde.

    Die Vorteile:

    • die Übersetzungen der Matrix-Koordinaten erfolgen an einer einzigen, zentralen Stelle, eben diesen Funktionen.
    • die Untermatrix muss nicht kopiert werden.
    • Die Funktionen sind "Bausteine", die es erleichtern den Code in einem anderen Kontext wiederzuverwenden und zu erweitern.

    Hinweis: Ich bin hier nicht auf Bereichs-Prüfungen eingegangen. Du solltest natürlich sicherstellen, dass bei deinen umgerechneten Koordinaten, die Größe der Matrizen immer berücksichtigt wird, und keine Schreib- oder Lesezugriffe außerhalb der Matrix stattfinden. In meinem Beispiel-Code oben habe ich das mithilfe eines assert() gemacht. GROSSE_MATRIX_M und GROSSE_MATRIX_N stehen hier für die Matrix-Grösse, also 963 und 672.

    * Da die Funktionen in dieser Form wahrscheinlich die selbe Berechnung ausführen, geht das natürlich auch mit einer Funktion. Packt man diese später vielleicht in eine Klasse, wo diese Funktionen dann intern auf die nn- und mm-Grössen der Matrizen zugreifen, landet man dann aber wahrscheinlich wieder bei zwei separaten Funktionen (aus dieser Richtung kommt mein Vorschlag).