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

[C++] Wymnożenie Macierzy

Ostatnio zmodyfikowano 2015-11-10 12:00
Autor Wiadomość
Deivid
Temat założony przez niniejszego użytkownika
[C++] Wymnożenie Macierzy
» 2015-10-19 23:47:12
Witajcie, jestem w trakcie nauki C++, mam za zadanie napisać program mnożący macierze.

Do tej pory udało mi się wypisać dwie macierze liczbami losowymi, jednak nie mogę zrobić ich mnożenia.
oto kod:
C/C++
for( int i = 0; i < l_kMacierz1; i++ )
for( int j = 0; j < l_wMacierz2; j++ )
for( int k = 0; k < l_wMacierz1; k++ )
     tabWynikowa[ i ][ j ] += tabMacierzy1[ i ][ k ] * tabMacierzy2[ k ][ j ];


Aby pomnozyc dwie macierze liczba kolumn pierwszej z nich
musi byc taka sama jak liczba wierszy drugiej


Wpisz rozmiar pierwszej macierzy
Wpisz liczbe kolumn:  5
Wpisz liczbe wierszy: 4

Wpisz rozmiar drugiej macierzy
Wpisz liczbe kolumn:  3
Wpisz liczbe wierszy: 5


Macierz pierwsza:
2       4       11      6       7
3       2       7       7       4
12      9       13      1       5
8       9       8       2       3

Macierz druga:
2       4       11
3       2       7
12      9       13
8       9       8
1       7       11


Macierz wynikowa:
255     206     135     124     169
186     129     96      110     135
329     213     205     241     213
246     139     164     183     162
281     273     183     140     220

Process returned 0 (0x0)   execution time : 4.623 s
Press any key to continue.



Edit:
Tu jest cały kod. Nie wiem już jak to naprawić (dodam że dopiero raczkuję w C++)
C/C++
//Mnożenie maicerzy v0.2.1
#include<iostream>
#include<string>
#include<cstdlib>
#include<ctime>
#include<cstdio>
using namespace std;
const int rozmTab = 100;

//Funkcja sluzy do wybierania wielkosci macierzy z jakiej bedzie korzystal uzytkownik
void wybierz_rozmiarTablicy( int & l_kolumnMacierzy, int & l_wierszyMacierzy )
{
    do
    {
        cout << "Wpisz liczbe kolumn:  ";
        cin.clear();
        cin.sync();
        cin >> l_kolumnMacierzy;
    } while( !cin.good() );
   
    do
    {
        cout << "Wpisz liczbe wierszy: ";
        cin.clear();
        cin.sync();
        cin >> l_wierszyMacierzy;
    } while( !cin.good() );
   
   
   
}
//Funkcja sprawdz czy macierz moze byc pomnozona
int sprawdzenieMacierzy( int l_kolumnMacierz1, int l_wierszyMacierz2 )
{
    if( l_kolumnMacierz1 == l_wierszyMacierz2 )
    {
        return true;
    }
    if( l_kolumnMacierz1 != l_wierszyMacierz2 )
    {
        cout << "Miales\as pamietac ze l. kolumn macierzy 1, nie moze byc rozna od l. wierszy macierzy drugiej";
        system( "pause" );
        return 0;
    }
}

int main()
{
    srand( time( NULL ) );
    //Teoria
    cout << "Aby pomnozyc dwie macierze liczba kolumn pierwszej z nich\nmusi byc taka sama jak liczba wierszy drugiej\n\n\n";
   
    //Deklarujemy tablice o stalej wielkosci
    int tabMacierzy1[ rozmTab ][ rozmTab ];
    int tabMacierzy2[ rozmTab ][ rozmTab ];
   
    //Wypisanie tablicy liczbami losowymi
    for( int i = 0; i < rozmTab; i++ )
    for( int k = 0; k < rozmTab; k++ )
    {
        tabMacierzy1[ i ][ k ] =(( rand() % 14 ) + 0 );
        tabMacierzy2[ i ][ k ] =(( rand() % 14 ) + 0 );
    }
   
    //Implementacja zmiennych uzytkownia, wykorzystana w wielkosci macierzy
    int l_kMacierz1, l_wMacierz1;
    int l_kMacierz2, l_wMacierz2;
   
    //Wypisanie zmiennych wielkosci macierzy
    cout << "Wpisz rozmiar pierwszej macierzy\n";
    wybierz_rozmiarTablicy( l_kMacierz1, l_wMacierz1 );
    cout << "\nWpisz rozmiar drugiej macierzy\n";
    wybierz_rozmiarTablicy( l_kMacierz2, l_wMacierz2 );
   
    //Sprawdzamy czy macierz moze zostac pomnozona
    if( sprawdzenieMacierzy( l_kMacierz1, l_wMacierz2 ) == true )
    {
        //Wypisujemy na ekran macierz pierwsza
        cout << "\n\nMacierz pierwsza:\n";
        for( int i = 0; i < l_wMacierz1; i++ )
        {
            for( int j = 0; j < l_kMacierz1; j++ )
            { cout << tabMacierzy1[ i ][ j ] << "\t"; }
            cout << "\n";
        }
       
        //Wypisujemy na ekran macierz druga
        cout << "\nMacierz druga:\n";
        for( int i = 0; i < l_wMacierz2; i++ )
        {
            for( int j = 0; j < l_kMacierz2; j++ )
            { cout << tabMacierzy1[ i ][ j ] << "\t"; }
            cout << "\n";
        }
       
        //Implementacja tablicy wynikowej
        int tabWynikowa[ rozmTab ][ rozmTab ];
       
        //Wypisanie tablicy wynikowej zerami
        for( int i = 0; i < rozmTab; i++ )
        for( int k = 0; k < rozmTab; k++ )
             tabWynikowa[ i ][ k ] = 0;
       
        //Mnozenie macierzy
        for( int i = 0; i < l_kMacierz1; i++ )
        for( int j = 0; j < l_wMacierz2; j++ )
        for( int k = 0; k < l_kMacierz1; k++ )
             tabWynikowa[ i ][ j ] += tabMacierzy1[ i ][ k ] * tabMacierzy2[ k ][ j ];
       
        //Wypisujemy na ekram tablice wynikowa
        cout << "\n\nMacierz wynikowa:\n";
        for( int i = 0; i < l_wMacierz2; i++ )
        {
            for( int j = 0; j < l_kMacierz1; j++ )
            { cout << tabWynikowa[ i ][ j ] << "\t"; }
            cout << "\n";
        }
    }
    return 0;
}

Edit 2. Wklejam nowe kody C++ do pierwszego postu (20.10.2015 19:45)
P-138909
carlosmay
» 2015-10-20 04:38:42
Macierz1 ma mniej o jedną kolumnę i wychodzisz poza zakres tablicy.
P-138914
Deivid
Temat założony przez niniejszego użytkownika
» 2015-10-20 09:02:09
Ale jest to macierz prostokątna. Nie muszę wprowadzać macierzy kwadratowej. Jeśli zgadza się liczba wierszy macierzy 1 z liczbą kolumn macierzy 2 to mogę je wymnożyć. Zgodnie z teorią, chyba że tutaj też mam braki :) Tak więc tam mogę wprowadzić różne wartości, a tam gdzie muszę takie same jest napisana funkcja sprawdzająca int która zwraca true w porównaniu.

Edit. Wiem, że mógłbym to zrobić na wskaźnikach i tablicy dynamicznej. Jednak jeszcze tego nie opanowałem. Dlatego program jest pisany tak krok po kroku.
Zastanawia mnie jeszcze czy mogłem w taki sposób zdefiniować zmienną stałą?
Chodzi mi o zapis:
C/C++
int zmienna_kolumny;
cin >> zmienna_kolumny;
const int zmienna_do_kolumn = zmienna_kolumny;
następnie wykorzystać tą zmienną do tablic. (moja wiedza kończy się że tablicę muszę zdefiniować od razu lub użyć właśnie zmienną stałą)
P-138921
carlosmay
» 2015-10-20 09:36:42
C/C++
int zmienna_kolumny;
cin >> zmienna_kolumny;
const int zmienna_do_kolumn = zmienna_kolumny;
 niestety różnią tablicy statycznej
musi być znany juz na etapie kompilacji więc to nie zadziała.

Jeżeli masz indeks 'k' dla obu macierzy to Maks 'k' musi być takie samo dla obu macierzy. Musisz pilnować żeby mnożyć przez wartości które są w tablicach.
Jak wyjdziesz poza tablicę system nie musi wywalić bledy a wyniki masz z kosmosu.
P-138922
Deivid
Temat założony przez niniejszego użytkownika
» 2015-10-20 09:41:35
Więc muszę np zadeklarować na wstępie że tablice mają np int tab[100], a później tylko użytkownik wprowadzi ile z tych 100 miejsc wykorzysta?
PS. Jakimś cudem ten program się kompiluje i działa ten zapis który podałem
P-138923
carlosmay
» 2015-10-20 11:18:14
Sprawdź jakie duże masz te tablice.
C/C++
int tab[ 5 ][ 4 ];
int rozm = sizeof( tab ) / sizeof( int );
 dla takiej tablicy wynik powinien być 20.

Sprawdź analogicznie u sobie.

PS. A tak na marginesie to wynikowa macierz powinna być chyba 3 x 5. (ale też byłem słaby z matmy, więc mogę się mylić)

Więc muszę np zadeklarować na wstępie
 dla statycznych tablic tak.
Dynamiczne tablice można w trakcie wykonywania programu ustalać.
Nie są aż takie trudne.
P-138924
Deivid
Temat założony przez niniejszego użytkownika
» 2015-10-20 19:50:17
Zmieniłem cały kod programu (widoczny w poście pierwszym), napisałem go po prostu od nowa. Zdefiniowałem odgórnie wielkość tablicy, nie cudując już z przypisaniem wartości zmiennej stałej przez zmienną wpisywaną przez użytkownika. Carlosmay, kojarzę już Twój nick przez to że wcześniej już się wypowiadałeś w moich tematach. Dzięki Ci wielkie za pomoc, jakbym miał możliwość to postawiłbym Ci piwko za to :). Domyślam się że nie jest to aż takie trudne, jednak nie mam czasu na pogłębienie wiedzy. Masa sprawozdań na uczelnie, eh te studia. W wolnej chwili od razu siadam i kończę kurs (na razie zatrzymałem się na 27 lekcji)

Wydaje mi się że program lepiej działa gdy wprowadzę zmianie w fragmencie mnożenia:
C/C++
//Mnozenie macierzy
for( int i = 0; i < l_kMacierz1; ++i )
for( int j = 0; j < l_wMacierz2; ++j )
for( int k = 0; k < l_kMacierz1; ++k )
     tabWynikowa[ i ][ j ] += tabMacierzy1[ i ][ k ] * tabMacierzy2[ k ][ j ];

zamiana dotyczy:
i++, j++, k++
 na
++i, ++j, ++k
Tak ogólnie do czego ta zmiana służy? Nie było to dokładnie wyjaśnione w kursie i jeszcze tego nie zrozumiałem.
P-138955
carlosmay
» 2015-10-20 21:07:46
i++, j++, k++na++i, ++j, ++k
 Tak ogólnie do czego ta zmiana służy? Nie było to dokładnie wyjaśnione w kursie i jeszcze tego nie zrozumiałem.
Było w jednej z lekcji, nie pamiętam dokładnie krórej. Jak wpadnie mi w ręce to podrzucę link.

Różnica jest tak, że preikrementacja ++i wykonuje się przed użyciem zmiennej 'i',
natomiast postinkrementacja i++ wykonuje się już po użyciu zmiennej 'i'.

Przykład:
cout << tab[ j++ ];
 wypisze wartość elementu tab[j] i później podniesie wartość 'j' o jeden.
cout << tab[ ++i ];
 analogicznie, wpierw podniesie się wartość 'i' o jeden, następnie zostanie wypisana wartość, czyli tab[i + 1]
P-138961
« 1 » 2
  Strona 1 z 2 Następna strona