Program do wykonywania dzialan na macierzach

0

Hej nie dziala mi jak trzeba mnozenie macierzy, chcialby ktos mi dac jakas wskazowke?
Bylabym wdzieczna

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;



	void czytaj(int **&a,int w,int k)
	{
   		a=new int *[w];
    	for(int i=0;i<w;i++)
    	a[i]=new int[k];	
	}

	void wypelnij(int **a,int w,int k)
	{
		for(int i=0;i<w;i++)
    		{
        		for(int j=0;j<k;j++)
        			{
            			a[i][j]=1 + rand()%20;
        			}
			}
	}
	
	void wyswietl(int **a,int w,int k)
	{
        for(int i=0;i<w;i++)
    		{
        		for(int j=0;j<k;j++)
        			{	
            			cout<<a[i][j]<<" ";
        			}
			}
	}

	void kasuj(int **a,int w,int k)
	{
    	for(int i=0;i<w;i++)
    		{
        		delete []a[i];
    		}
    			delete[]a;
	}

	void suma(int **a,int **b,int w1,int k1)	
	{   
		int dodaw[w1][k1];
    		for(int i=0;i<w1;i++)
    		{   
				for(int j=0;j<k1;j++)
        		{
					dodaw[i][j]=a[i][j]+b[i][j];
        				cout<<dodaw[i][j]<<" ";
    			}
   			}

	}

	void odejmowanie(int **a,int **b,int w1,int k1)
	{   
		int odejmowanie[w1][k1];
    		for(int i=0;i<w1;i++)
    			{   
					for(int j=0;j<k1;j++)
        				{
							odejmowanie[i][j]=a[i][j]-b[i][j];
        						cout<<odejmowanie[i][j]<<" ";
    					}
   				}

	}

	void mnozenie(int **a,int **b, int **c, int w1, int k1)
	{   
		int mnozenie[w1][k1];
    		for(int i=0;i<w1;i++)
    			{   
					for(int j=0;j<k1;j++)
    					{ 
							c[i][j]=0;
								for(int k=0;k<k1;k++)
    								{
										c[i][j]=(a[i][k]*b[k][j])+c[i][j];
												cout<<c[i][j]<<" ";
    								}	
						}
				}	
	}

	int main()
		{   
			srand(time(0)); //losowe liczby do macierzy
	 
			int b,c,d,e;
    		int **tab1,**tab2, **tab3;
    		cout<<"Podaj rozmiar Macierzy A - liczba wierszy: \n";
    			cin>> b;
    		cout<<"Podaj rozmiar Macierzy A - liczba kolumn: \n";
    			cin>>c;
    		cout<<"Podaj rozmiar Macierzy B - liczba wierszy: \n";
    			cin>>d;
    		cout<<"Podaj rozmiar Macierzy B - liczba kolumn: \n";
    			cin>>e;
    
			czytaj(tab1,b,c);
    		czytaj(tab2,d,e);
    
    		wypelnij(tab1,b,c);
    		wypelnij(tab2,d,e);
    
    		cout << "Macierz A: \n";
    		wyswietl(tab1,b,c);
    		cout<<endl;
    
    		cout << "Macierz B: \n";
    		wyswietl(tab2,d,e);
    		cout<<endl;
    
   	
   			if (b == d && c == e )
   				{
   					cout << "Wynik dodawania macierzy A i B wynosi: \n\n";
						suma(tab1,tab2,b,c);
				}
			else 
				{
					cout<< "Macierzy nie mozna dodac !	Macierze musza miec ten sam rozmiar\n\n";
				}
	
			if (b == d && c == e )
   				{
   					cout << "Wynik odejmowanie macierzy A i B wynosi: \n";
						odejmowanie(tab1,tab2,b,c);
				}
			else 
				{
					cout<< "Macierzy nie mozna odjac !	Macierze musza miec ten sam rozmiar\n\n";
				}
	
			if ( c != d)
   				{
   					cout<< "Macierzy nie mozna pomnozyc !	\nIlosc kolumn macierzy A nie rowna sie ilosci wierszy macierzy B!!\nSprobuj ponownie\n\n";
   				}
			else 
				{
					cout << "Wynik mnozenia macierzy A i B wynosi: \n\n";
						mnozenie(tab1,tab2,tab3, b, d);	
				}
    
    
    
    			kasuj(tab1,b,c);
    			kasuj(tab2,d,e);


    return 0;
}
0

Co to jest int mnozenie[w1][k1];? A to c[i][j]=(a[i][k]b[k][j])+c[i][j];?

0

Używasz podwójnych wskaźników co pokazuje że całkiem dobrze rozumiesz C++. Czy to jest twój kod?

2

Jak sobie pościelisz tak się wyśpisz:

struct Matrix { double/*int?*/ *data; size_t y,x; };
Matrix create(size_t y,size_t x) { return {new double[y*x],y,x}; }
void dispose(Matrix &m) { delete[] m.data; }
double &data(Matrix &m,size_t y,size_t x) { return *(m.data+y*m.x+x); }
const double &data(const Matrix &m,size_t y,size_t x) { return *(m.data+y*m.x+x); }
Matrix add(const matrix &a,const matrix &b) { /*...*/ }
void print(const Matrix &m)
{
	for(size_t y=0;y<m.y;++y,cout<<endl) for(size_t x=0;x<m.x;++x) cout<<data(m,y,x)<<' ';
}

A jeszcze lepiej zrób z tego klasę z przeciążeniami operatorów.

1

https://wandbox.org/permlink/ktsqg27KDrddnreY
zwróć uwagę, że to ma około 200 linii kodu (mniej więcej tyle co twój kod 150), a jest czytelne łatwe w zrozumieniu i robi znacznie więcej.

0
void mnozenie(int **a,int **b, int **c, int w1, int k1)
{   
    czytaj(c,w1,k1);
    for(int i=0;i<w1;i++)
    {   
        for(int j=0;j<k1;j++)
        { 
            for(int k=0;k<k1;k++)
            {
                c[i][j]+=(a[i][k]*b[k][j]); 
            }  
            cout<<c[i][j]<<" ";
        }
    } 
    cout<<endl; 
}

wywołanie : mnozenie(tab1,tab2,tab1, b, d);
deklaracje int **tab3 wywal bo i tak przekazaną tablice zerujesz;

Przy kompilacji warto użyć dodatkowo -Wall, które pokaże ci potencjalne błędy. Na przyszłość jeżeli jakaś część programu ci "nie działa" to nie wklejaj całego kodu tylko jego część.

2

Po co robić dwuwymiarową tablicę i komplikować sobie całe rozwiązanie, jak można zrobić po ludzku - jedną tablicę o długości rows * columns?
Wtedy odpada ta dzika zabawa wskaźnikami, bo jest jedna ciągła tablica (co już samo w sobie może być zaletą bo procesor lubi jak się operuje na jednym kawałku pamięci https://en.wikipedia.org/wiki/Locality_of_reference ).

Tylko mając jednowymiarową tablicę, trzeba potem przeliczać pozycje elementów:
y * columns + x
albo
x * rows + y
Zależy, w którą stronę trzymać w pamięci https://en.wikipedia.org/wiki/Row-_and_column-major_order

Poza tym jak się uprzeć, to pętle też można wywalić i zrobić na pałę. Przeglądając kod GL Matrix (JSowa biblioteka do macierzy) widzę, że oni nie używają tam nawet pętli: https://github.com/toji/gl-matrix/blob/master/src/mat4.js

tylko, że przypuszczam, że tam chodziło o optymalizację i pragmatyzm, a nie o elegancję czy elastyczność (tam zakładają, że macierz zawsze będzie miała taki sam rozmiar).

0

Dodam tylko od siebie że umiejętność budowania nieregularnych struktur danych przy pomocy wskaźników a zwłaszcza podwójnych wskaźników oraz niedopuszczalne do wycieku pamięci to chyba największa sztuka w C/C++.

1 użytkowników online, w tym zalogowanych: 0, gości: 1