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: 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++) #include<iostream> #include<string> #include<cstdlib> #include<ctime> #include<cstdio> using namespace std; const int rozmTab = 100;
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() ); }
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 ) ); cout << "Aby pomnozyc dwie macierze liczba kolumn pierwszej z nich\nmusi byc taka sama jak liczba wierszy drugiej\n\n\n"; int tabMacierzy1[ rozmTab ][ rozmTab ]; int tabMacierzy2[ rozmTab ][ rozmTab ]; 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 ); } int l_kMacierz1, l_wMacierz1; int l_kMacierz2, l_wMacierz2; cout << "Wpisz rozmiar pierwszej macierzy\n"; wybierz_rozmiarTablicy( l_kMacierz1, l_wMacierz1 ); cout << "\nWpisz rozmiar drugiej macierzy\n"; wybierz_rozmiarTablicy( l_kMacierz2, l_wMacierz2 ); if( sprawdzenieMacierzy( l_kMacierz1, l_wMacierz2 ) == true ) { 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"; } 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"; } int tabWynikowa[ rozmTab ][ rozmTab ]; for( int i = 0; i < rozmTab; i++ ) for( int k = 0; k < rozmTab; k++ ) tabWynikowa[ i ][ k ] = 0; 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 ]; 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) |
|
carlosmay |
» 2015-10-20 04:38:42 Macierz1 ma mniej o jedną kolumnę i wychodzisz poza zakres tablicy. |
|
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: 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łą) |
|
carlosmay |
» 2015-10-20 09:36:42 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. |
|
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 |
|
carlosmay |
» 2015-10-20 11:18:14 Sprawdź jakie duże masz te tablice. 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. |
|
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: 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. |
|
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] |
|
« 1 » 2 |