Mehrdimensionale Arrays; dynamischer Speicher;



  • Okay, stimmt statt

    if(M && N ==0)
    

    kann/sollte ich schreiben:

    if (m<=0 && n<=0)
    

    Laut dem UML-Klassendiagramm wird m_rows und m_cols mit 2 initialisiert.
    Ich dachte, dass ich das im Konstruktor definieren muss.

    Oh, tut mir leid, in Wirklichkeit gibt es diese Klammer :S.

    Ich habe leider nicht so einen großen Spielraum.
    Das ist eine Aufgabe von der Uni und ich muss mich an das Klassendiagramm halten :/. size_t kenne ich noch gar nicht, für was steht dieser Datentyp?

    Mh, irgendwie dachte ich die gehören dahin, hast recht ohne die Klammern funktionierts 🙂

    Ich schau mal ob noch weitere Probleme auftreten, ich muss das Projekt eh heute noch fertigstellen, also bitte den Thread nicht schließen.

    Vielen Dank für Eure hilfe 🙂



  • ...



  • CMatrix(int M = 2, int N = 2)
    

    Wenn nichts angegeben, sollen M und N 2 sein. (Beachte: Kein CMatrix:: davor, das muss nämlich in die Klassendefinition)



  • Okay, hab ich so übernommen patrick246 😉

    Ich saß noch bis spät Abends an meinem Programm.
    Bei meinem Programm stimmt nur ne Kleinigkeit noch nicht.

    In der main habe ich folgende Schleife :

    int M, N;
    	M = 4; N = 3;
    	matrix.getDimension(M,N);
    	int m =1;
    	int v =0;
    
    	for(int n=1; m<=M ;n++)
    	{
    		matrix.setElementAt(m,n,v);
    		abs(v);
    		v++;
    
    		if (v % 2 != 0) {v = v *-1;}
    
    		if(n==N)
    		{
    			n = 0; m++;
    		}
    
    	}
    

    Eigentlich soll ich ein Matrix-Feld von :

    0 -1 2
    -3 4 -5
    6 -7 8
    -9 10 -11

    aufbauen. Raus kommt jedoch :

    0 -1 0
    -1 -1 -1
    0 -1 0
    -1 0 -1

    und ich weiß einfach nicht wieso 😕

    An setElementAt hat sich nichts verändert 😞

    Ich Danke euch für Eure Hilfe 😕



  • 1. Was macht getDimension? Dem Namen nach sollte sie die Dimensionen der Matrix zurückgeben, stattdessen nimmt sie Werte entgegen.

    2. Eine NxM-Matrix kannst du mit folgender Schleife durchlaufen, angenommen die erste Position ist (0|0) und die letzte Position ist (N-1|M-1):

    int counter = 0;
    for(int n = 0; n < N; ++n)
    {
        for(int m = 0; m < M; ++m)
        {
            if((counter % 2) == 0)
                matrix.setElementAt(n, m, counter);
            else
                matrix.setElementAt(n, m, -counter);
        }
    }
    

    3. getArrayIndex

    std::size_t getArrayIndex(std::size_t y, std::size_t x)
    {
        return y * m_breite + x;
    }
    

    4. setElementAt

    void setElementAt(std::size_t y, std::size_t x, double value)
    {
        m_data[getArrayIndex(y,x)] = value;
    }
    

    Stimmen die letzten beiden ungefähr mit deinem Code überein?



  • Quadknick schrieb:

    CMatrix::CMatrix(int M, int N)
    {
       if(M && N ==0) 
       {
         m_rows =2; m_cols=2;
       }
       else 
         m_rows = M; m_cols=N; m_size = m_rows*m_cols;
    
         m_pArray = new double [m_size];
    

    der else Zweig sieht auch sehr ungesund aus



  • int CMatrix::getArrayIndex(int m ,int n)
    {
       double i=0;
       if(//zusicherungen)
       {
         i=(m-1)*n+n-1; return i; // <====== *n muss *m_cols heissen!
       }
       else if(//zusicherungen)
       {
         return -1;
       } 
        return 0;
    

    Und 1-basierte Indexe sind selten ne gute Idee.



  • Hey Leute,

    ich war am Dienstag im Labor und da haben wir den Fehler schnell gefunden.
    Hustbaer du hast recht! n muss m_cols heissen.

    Desweiteren habe ich die main-Schleife folgendermassen umprogrammiert :

    int z=1; int v=0; int M,N; M=4, N =3;
    matrix.getDimension(M,N);
    for(int m=1; m<M; m++)
    {
       for(int n=1;n<=N;n++)
       {
          matrix.setElementat(m,n,z*v);
          v++;
          z *= -1; 
       }
    }
    
    matrix.print();
    

    Nun habe ich wie folgt ein neues Problem.
    Wir sollten der CMatrix Klasse weitere Methoden hinzufügen
    und dabei

    enum
    

    benutzen.

    enum INI_MODE{INIT_ZEROS, INIT_UNIT,INIT_RAND}
    

    Die zugefügten Methoden lauten :

    CMatrix(int dm, INI_MODE mode = INIT_ZEROS);
    void operator *= (float rop);
    CMatrix& operator = (const CMatrix& rop)const;
    CMatrix operator + (const CMatrix& rop)const;
    CMatrix operator * (const CMatrix& rop)const;
    friend ostream& operator << (ostream& lop, const CMatrix& rop);
    

    Ich habe schon einige implementiert und hänge nun bei dem Zuweisungsoperator 😕

    Dafür sollten wir uns an ein Aktivitätsdiagramm halten :

    ..............................Start :

    [Speichergröße der
    Operanden stimmt nicht......(Anzeige einer Meldung)
    überein]....................(Freigeben des alten Speicherplatzes)
    ............................(Allokieren von Speicher der Größe des
    .............................rechten Operanden)
    ............................(aktualisieren des Attributs der Speichergröße)

    [Speichergröße der
    Operanden stimmt............(if schleife erfüllt)
    überein]

    [Anzahl von Zeilen oder
    Spalten stimmt nicht bei.....(aktualisieren der Attribute für
    beiden Operanden überein]....Zeilen - und Spaltenzahl)

    [Anzahl von Zeilen oder
    Spalten stimmt nicht bei.....(if Schleife erfüllt)
    beiden Operanden überein]

    .............................(Kopieren der Matrix-Elemente
    .............................des rechten Operanden in das Array
    .............................des linken Operanden)
    .............................(Der linke Operand gibt sich selbst zurück)

    ............................ Ende:

    Mein Code sind folgendermaßen aus :

    CMatrix& CMatrix ::operator = (const CMatrix& rop)const
    {
    	int m_cols2 = rop.m_cols;
    	int m_rows2 = rop.m_rows;
    	int m_size2 = m_cols2 * m_rows2;
    
    	double* m_Array;
    	m_Array = new double [m_size2];
    
    	if (m_size2 == rop.m_size)
    	{
    		if (m_cols2 == rop.m_cols && m_rows2 == rop.m_rows)
    		{
    			int v = rop.getArrayIndex(rop.m_rows, rop.m_cols);
    			int z = rop.getArrayIndex(m_rows2, m_cols2);
    
    				for(int m = 1; m<=rop.m_rows; m++)
    				{
    					for(int n=1; n<=rop.m_cols ;n++)
    					{
    						m_pArray[v] = m_Array[z];
    
    					}
    
    				}
    
    		}
    
    	}
    	else if (m_size2 != rop.m_size )
    	{
    		cout << "veraendere Groesse der Matrix!"<<endl;
    		delete [] m_Array;
    		m_Array = new double [rop.m_size];
    
    		if (m_cols2 != rop.m_cols && m_rows2 != rop.m_rows)
    		{
    			m_cols2 = rop.m_cols;
    			m_rows2 = rop.m_rows;
    
    			int v = rop.getArrayIndex(rop.m_rows, rop.m_cols);
    			int z = rop.getArrayIndex(m_rows2, m_cols2);
    
    			for(int m = 1; m<=rop.m_rows; m++)
    			{
    				for(int n=1; n<=rop.m_cols ;n++)
    				{
    
    					m_pArray[v] = m_Array[z];
    				}
    
    			}
    		}
    
    	}
    
    }
    

    Ich glaube ich hab ein Problem mit der Vorstellung welcher operand rechts und welcher Links steht 😕 das im Parameter übergebene Objekt ist das der rechte
    oder der Linke Operand? 😕
    Zu dem erhalte ich den Fehler no return..aber einen der Zeiger zurückzugeben funktioniert nicht :S

    weiß jemand einen Rat?

    Vielen Dank und tut mir leid, dass ich wieder mit was neuem beginne :S



  • // links |   rechts
       x     +     y;
       x.operator+(y); // Die obere Variante ist nur die faule, schönere Schreibweise.
    

    Offensichtlich ist der Operand rechts vom Operator der Parameter. Und der Operand links vom Operator ist das Objekt, das verändert wird. 😉

    Logischerweise willst du das veränderte Objekt zurückgeben, für den Fall, dass andere Funktionen sofort mit dem veränderten Objekt weiterarbeiten können, also return *this;



  • + als Operator zu wählen, war natürlich doof. Denk dir einfach = statt + in meinem Beispiel. 😃


Anmelden zum Antworten