Macierz dwuwymiarowa, wprowadzenie odpowiedniej ilości danych oraz działania

0

Dobry, bawię się jako początkujący z c++ i staram się łapać podstawy tego języka. W związku z czym w wolnym czasie bawię się w różne podstawowe operacje, które mam podesłane przez kolegę i ostatnim czasem miałem temat tak jak w tytule, macierze dwuwymiarowe oraz działania związanie z nimi tzn. dodawanie, odejmowanie oraz mnożenie. Podszedłem do tematu na tyle na ile potrafię i doszedłem do momentu tworzenia tabeli, lecz potrzebuje pomocy (kod programu będzie załączony) w tym, aby do wybranych rozmiarów tabeli, dobierało odpowiednie ilości tych elementów, które należy wpisać, a następnie aby robić na nich wspomniane działania. Program:

using namespace std;
int main() 
{
int **tab, k, w,i,j;
	cout<<"Liczba wierszy: ";
	
	cin>>w;
	
	tab = new int *[w]; //przydzielenie pamięci na w wierszy
	
	for(int i=0;i<w;i++)
	{
		cout<<"Liczba komórek w wierszu nr:  "<<i<<": ";
		cin>>k;
		tab[i] = new int[k]; //przydzielenie dla każdego wiersza po k komórek
	}
	 cout<<"Elementy tablicy: "<<endl;
    for(int i=0; i<k; i++) //zmienna "i"
    {
        for(int j=0; j<k; j++)
        {
            cout<<i<<"."<<j<<" element tablicy ";
            cin>>tab[i][j];
        }
        cout<<endl;
    }
    cout<<"Tablica: "<<endl;
    for(int i=k; i>=0; i--)
    {
        for(int j=k; j>=0; j--)
        {
        cout<<i<<"."<<j<<" element tablicy "<<tab[i][j];   
        }
        cout<<endl;
    }
	
}

3

Radziłbym nauczyć się definiować własne funkcje.
Dzięki temu czytelniej i logiczniej będziesz dzielił kod. Obecna wersja jest trudna do czytania.
Poza tym polecam artykuł od kq: https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete Większość kursów się nie stosuje do rad z tego artykułu, bo jest klonem starych kursów, które są oparte o książki i standardy z lat 90tych.

Narzędzie automatycznie wykrywa błąd w twoim kodzie: https://godbolt.org/z/Kf6q7jz6d

W skrócie zakres pętli for przy wypisywaniu macierzy jest zły. Nie rozumiem też czemu indeksujesz odwrotnie i czemu w tym kodzie każdy wiersz może mieć inny rozmiar (informacja o tych różnicach jest tracona)

twój kod poprawiony o powyższe rady (nadal nie jest dobrze, ale większe poprawki namąciłyby ci w głowie, a tak to powinno cię skierować we właściwym kierunku).

2

Nie lepiej pobierać dane o tablicy z jakiegoś pliku?
Bo inaczej, żeby przetestować program, będziesz musiał za każdym razem ręcznie wpisywać wszystkie liczby (chyba, że przekierujesz plik na standardowe wejście?)

czemu w tym kodzie każdy wiersz może mieć inny rozmiar (informacja o tych różnicach jest tracona)

No właśnie. Może to jakiś specjalny rodzaj macierzy, bo te, które znam, są prostokątne. Ale kto wie, matematyka rozległą jest.

Anyway, jak chcesz zapisać prostokątną macierz, to zwykle nie robi się tego tak:

//przydzielenie pamięci na w wierszy
//przydzielenie dla każdego wiersza po k komórek

(nazewnictwo w = wiersz, k = komórka(kolumna?) jest dzikie, ale niech już będzie).

tylko raczej trzyma się macierze w jednym ciągłym obszarze:

 //przydzielenie pamięci na (w wierszy * k komórek)

wtedy się odwołujesz

tab[y * k + x]; 

albo

tab[x * w + y]; 

(column major vs. row major: https://en.wikipedia.org/wiki/Row-_and_column-major_order )

Trzymanie liczb w jednym ciągłym obszarze pamięci ma zalety, że 1. jest to potencjalnie bardziej wydajne 2. kod jest prostszy, bo nie trzeba alokować dynamicznie każdego rzędu/kolumny 3. łatwiej przekazać taką macierz w buforze do karty graficznej 4. łatwiej sklonować taką macierz, bo w pamięci będzie to zwykła 1-wymiarowa tablica liczb itp.

Czyli ogólnie względy praktyczne (chociaż jak robisz ćwiczebny program, to może niekoniecznie cię dotyczą, poza punktem 2.)

mnożenie

Żeby mnożyć macierze, musisz zrozumieć, jak to działa od strony matematycznej. Jak zrozumiesz i będziesz umiał pomnożyć na papierze, to będziesz umiał również pomnożyć je na kompie.

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