Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

C++ operator mnożenia dla macierzy

Ostatnio zmodyfikowano 2016-04-22 11:51
Autor Wiadomość
jolkaaa3
Temat założony przez niniejszego użytkownika
C++ operator mnożenia dla macierzy
» 2016-04-19 20:48:27
Witam, potrzebuję pomocy w napisaniu programu w języku C++. Chodzi o dopisanie do klasy Macierz operatorów „*” i „*=”. Proszę o pomoc bo pogubiłam się w tym.

C/C++
#include<iostream>
#include<cstdlib>
using namespace std;

class Macierz {
private:
    int ** elementy;
    int liczba_wierszy;
    int liczba_kolumn;
    void alokuj( int liczba_wierszy, int liczba_kolumn ) {
        elementy = new int *[ liczba_wierszy ]; //tablica wierszy
        for( int i = 0; i < liczba_wierszy; i++ ) {
            elementy[ i ] = new int[ liczba_kolumn ];
        }
    }
   
    void usun() {
        for( int i = 0; i < liczba_wierszy; i++ ) {
            delete[] elementy[ i ];
        }
        delete[] elementy;
    }
   
    void kopiuj( const Macierz & m ) {
        this->liczba_wierszy = m.liczba_wierszy;
        this->liczba_kolumn = m.liczba_kolumn;
        alokuj( liczba_wierszy, liczba_kolumn );
        for( int i = 0; i < liczba_wierszy; i++ ) {
            for( int j = 0; j < liczba_kolumn; j++ ) {
                elementy[ i ][ j ] = m.elementy[ i ][ j ];
            }
        }
    }
   
public:
    int wysokosc() const {
        return liczba_wierszy;
    }
   
    int szerokosc() const {
        return liczba_kolumn;
    }
   
   
    Macierz operator +=( const Macierz & m ) {
        if( m.liczba_kolumn != liczba_kolumn || m.liczba_wierszy != liczba_wierszy ) {
            cerr << "Nie da się dodać tych macierzy" << endl;
            exit( 1 );
        }
        for( int i = 0; i < liczba_wierszy; i++ ) {
            for( int j = 0; j < liczba_kolumn; j++ ) {
                elementy[ i ][ j ] += m.elementy[ i ][ j ];
            }
        }
        return * this;
    }
   
    Macierz operator +( const Macierz & m ) const {
        Macierz wynik = m;
        wynik += * this;
        return wynik;
    }
   
   
   
    Macierz( int liczba_wierszy, int liczba_kolumn ) { // Konstruktor
        this->liczba_wierszy = liczba_wierszy;
        this->liczba_kolumn = liczba_kolumn;
        alokuj( liczba_wierszy, liczba_kolumn );
        for( int i = 0; i < liczba_wierszy; i++ ) {
            for( int j = 0; j < liczba_kolumn; j++ ) {
                elementy[ i ][ j ] = 0;
            }
        }
    }
    Macierz( const Macierz & m ) { //konstruktor kopiujacy
        kopiuj( m );
    }
   
    Macierz & operator =( const Macierz & m ) {
        if( & m != this ) {
            usun();
            kopiuj( m );
        }
        return * this;
    }
   
    ~Macierz() { // Destruktor
        usun();
    }
   
    int & element( int i, int j ) {
        return elementy[ i ][ j ];
    }
};

ostream & operator <<( ostream & out, Macierz & m ) {
    for( int i = 0; i < m.wysokosc(); i++ ) {
        for( int j = 0; j < m.szerokosc(); j++ ) {
            out << m.element( i, j ) << ' ';
        }
        out << '\n';
    }
    return out;
}

istream & operator >>( istream & in, Macierz & m ) {
    for( int i = 0; i < m.wysokosc(); i++ ) {
        for( int j = 0; j < m.szerokosc(); j++ ) {
            in >> m.element( i, j );
        }
    }
    return in;
}

int main() {
    Macierz a( 5, 7 );
    Macierz c = a;
    Macierz d( 1, 1 );
    c.element( 2, 3 ) = 4;
    a.element( 2, 3 ) = 1;
    c.element( 1, 3 ) = 1;
    c.element( 1, 3 ) = 4;
   
    d = a + c;
    cout << d << endl;
   
}
P-147445
Gibas11
» 2016-04-19 22:20:03
Przez mnożenie macierzy mam rozumieć zapisanie wyników operacji mnożenia odpowiadających sobie pól do nowej macierzy, tak?
Rozgryzłem o co chodzi, nawet trafiłem. ;-)

W każdym razie na bazie twojego kodu skleciłem coś takiego:
C/C++
Macierz operator *=( const Macierz & m ) {
    if( m.liczba_kolumn != liczba_kolumn || m.liczba_wierszy != liczba_wierszy ) {
        cerr << "Nie da się pomnożyć tych macierzy" << endl;
        exit( 1 );
    }
    for( int i = 0; i < liczba_wierszy; i++ ) {
        for( int j = 0; j < liczba_kolumn; j++ ) {
            elementy[ i ][ j ] *= m.elementy[ i ][ j ];
        }
    }
    return * this;
}

/*...*/

Macierz operator *( const Macierz & m ) const {
    Macierz wynik = m;
    wynik *= * this;
    return wynik;
}
Ale czegoś chyba nie zrozumiałem bo poszło za łatwo. :\

EDIT: Szybki test z taką funkcją main:
C/C++
int main() {
    Macierz a( 2, 2 ), b( 2, 2 ), c( 1, 1 );
   
    a.element( 0, 0 ) = 1;
    a.element( 0, 1 ) = 2;
    a.element( 1, 0 ) = 3;
    a.element( 1, 1 ) = 4;
   
    b.element( 0, 0 ) = 2;
    b.element( 0, 1 ) = 2;
    b.element( 1, 0 ) = 2;
    b.element( 1, 1 ) = 2;
   
    c = a * b;
   
    cout << c << endl;
}
dowodzi, że mój kod działa, ale mam wątpliwości czy w ogóle rozumiesz resztę, bo moje zmiany ograniczyły się do podmienienia
+
 na
*
 w 4 miejscach i drobnej poprawki w komunikacie przy próbie mnożenia różnych macierzy.
P-147451
jolkaaa3
Temat założony przez niniejszego użytkownika
» 2016-04-21 13:22:53
Rozumiem resztę kodu, jednak napisany przez Ciebie operator mnożenia macierzy chyba daje błędny wynik.
P-147488
carlosmay
» 2016-04-21 15:16:00
napisany przez Ciebie operator mnożenia macierzy chyba daje błędny wynik.
Opisz dokładnie problem i spodziewany wynik.
Nie trzeba wtedy rozkminiać cudzego kodu i domyślać się o co chodzi autorowi.

Czytelny opis problemu = Szybka i rzeczowa odpowiedź
P-147491
jolkaaa3
Temat założony przez niniejszego użytkownika
» 2016-04-21 15:26:39
Do klasy Macierz muszę dopisać operatory mnożenia dwóch macierzy „*” i „*=”, najpierw napisać operator „*” i za jego pomocą napisać „*=”.
P-147493
jolkaaa3
Temat założony przez niniejszego użytkownika
» 2016-04-21 16:20:58
Napisałam taki operator mnożenia

C/C++
Macierz operator *( const Macierz & m ) const {
    if( liczba_kolumn != m.liczba_wierszy ) {
        cerr << "Nie da sie pomnozyc tych macierzy" << endl;
        exit( 1 );
    }
    Macierz wynik( liczba_wierszy, m.liczba_kolumn );
    for( int i = 0; i < m.liczba_wierszy; i++ ) {
        for( int j = 0; j < m.liczba_kolumn; j++ ) {
            wynik.elementy[ i ][ j ] = 0;
            for( int k = 0; k < liczba_kolumn; k++ )
                 wynik.elementy[ i ][ j ] +=( elementy[ i ][ k ] * m.elementy[ k ][ j ] );
           
        }
    }
    return wynik;
}

Ale w dalszym ciągu nie działa poprawnie.
Gdy w funkcji głównej mam

C/C++
int main() {
    Macierz a( 3, 2 ), b( 2, 1 ), c( 3, 1 );
   
    a.element( 0, 0 ) = 1;
    a.element( 0, 1 ) = 2;
    a.element( 1, 0 ) = 3;
    a.element( 1, 1 ) = 4;
    a.element( 2, 0 ) = 5;
    a.element( 2, 1 ) = 6;
   
    b.element( 0, 0 ) = 1;
    b.element( 1, 0 ) = 2;
   
    c = a * b;
   
    cout << c << endl;
}

Powinno wyświetlić macierz
5   
11                
17
a wyświetla
5
11
0                

Czy ktoś mógłby mi pomóc to poprawić?
P-147496
Monika90
» 2016-04-21 16:34:06
C/C++
for( int i = 0; i < m.liczba_wierszy; i++ ) {

Tutaj zamiast m.liczba_wierszy powinno być liczba_wierszy
P-147497
jolkaaa3
Temat założony przez niniejszego użytkownika
» 2016-04-21 16:48:24
Rzeczywiście działa, dziękuje.
Teraz nie wiem, jak na podstawie operatora * napisać operator *=
P-147498
« 1 » 2
  Strona 1 z 2 Następna strona