Zmiana tabeli jednowymiarowej na tabelę dwuwymiarową

0

Witam, mam za zadanie zmodyfikować program na tworzenie tabeli jednowymiarowej na dwuwymiarową. Gdy podaję argument dla tab[1][0] i naciskam enter program wyłącza się. Czy ktoś mógłby mi doradzić gdzie w kodzie mam błąd.

#include <iostream>
using namespace std;


struct tablica
{
    int **dane;
    int rozmiar;
    int rozmiar1;
};

void inicjuj(tablica &tab, int wysokosc, int szerokosc)
{
    tab.rozmiar = wysokosc;
    tab.rozmiar1 = szerokosc;
    int **dane = new int *[tab.rozmiar];
    for(int i=0; i<tab.rozmiar; i++)
    {
        dane[i] = new int[tab.rozmiar1];
    }
}
void wypisz(const tablica &tab)
{
    if(tab.rozmiar < 1 && tab.rozmiar1 < 1)
    {
        cout << "Pusta tablica";
    }
    else
    {
        for (int i=0; i<tab.rozmiar; i++)
        {
            for (int j=0; j<tab.rozmiar1; j++)
            {
                cout << tab.dane[i][j] << " ";
        }
	}
    }
    cout << endl;
}

void wczytaj(tablica &tab)
{
    if(tab.rozmiar < 1 && tab.rozmiar1 < 1)
    {
        cout << "Pusta tablica";
    }
    else
    {
        for(int i=0; i<tab.rozmiar; i++)
        {
            for(int j=0; j<tab.rozmiar1; j++)
            {
                //cout<<"["<<i<<"]["<<j<<"]"<<endl;
                cout << "Podaj wartosc nr ["<< i+1  << "][" << j+1 << "]" << ": ";
                cin >> tab.dane[i][j];
            }
        }
    }
}

void zwolnij(tablica &tab)
{
    delete []tab.dane;
    tab.dane = NULL;
    tab.rozmiar = 0;
    tab.rozmiar1 = 0;
}

int main()
{
    tablica mojaTablica1;

    inicjuj(mojaTablica1, 2, 2);

    wczytaj(mojaTablica1);

    wypisz(mojaTablica1);

    zwolnij(mojaTablica1);

    wypisz(mojaTablica1);
}

1
    //int **dane = new int *[tab.rozmiar];
    tab.dane = new int *[tab.rozmiar];
    for(int i=0; i<tab.rozmiar; i++)
    {
        //dane[i] = new int[tab.rozmiar1];
        tab.dane[i] = new int[tab.rozmiar1];
    }

Poza tym:

  • używaj nazw angielskich
  • nigdy nie stosuj mało mówiących nazw jak rozmiar1 czemu nie width/height lub rows/cols?
  • przy zwolnieniu brakuje zwolnienia wierszy for(int r=0;r<tab.rows;++r) delete[] tab.data[r];
  • przy iteracjach po tablice dwuwymiarowej używaj par x y lub r c lub row col użycie innych par to zwiększenie prawdopodobieństwa błędu mniej więcej 10 krotnie.
  • http://forum.4programmers.net/1101404
0

Jeśli mogę jeszcze o coś zapytać. Kolejnym punktem jest przerobienie fragmentu kodu który łączy dwie tabele w jedną a później dodaje do niej konkretną wartość.
To jest kod który mam przerobić:

tablica polacz (const tablica &tab1, const tablica &tab2)
{
    tablica wynik;
    
    inicjuj(wynik, tab1.rozmiar + tab2.rozmiar);
    
    for(int i=0; i<tab1.rozmiar; i++)
    {
        wynik.dane[i] = tab1.dane[i];
    }
    for(int j=0; j<tab2.rozmiar; j++)
    {
        wynik.dane[tab1.rozmiar + j] = tab2.dane[j];
    }
    return wynik;
}
void dodajElement(tablica &tab, int nowy)
{
    //przydzielmy większą pamięć
    int *noweDane = new int[tab.rozmiar + 1];
    
    //przepisujemy stare wartości
    for(int i=0; i<tab.rozmiar; i++)
    {
        noweDane[i] = tab.dane[i];
    }
    //dopisujemy na końcu nową wartość
    noweDane[tab.rozmiar] = nowy;
    
    //zwalniemy starą pamięć
    delete []tab.dane;
    
    //przypusujemy nową pamięć (większą)
    tab.dane = noweDane;
    //zwiększamy rozmiar tablicy
    tab.rozmiar++;
}

Czy ktoś mógłby doradzić jak powinienem się za to zabrać?. na razie mam coś takiego:

tablica polacz (const tablica &tab1, const tablica &tab2)
{
    tablica score;

    inicjuj(score, tab1.cols+tab2.cols, tab1.rows+tab2.rows);

    for(int x=0; x<tab1.cols; ++x)
    {
        for(int y=0; y<tab1.rows; ++y)
        {
            score.data[x][y] = tab1.data[x][y];
        }
    }
    for(int x=0; x<tab2.cols; ++x)
    {
        for(int y=0; y<tab2.rows; ++y)
        {
            score.data[tab1.rows+ x][tab1.cols+ y] = tab2.data[x][y];
        }
    }
    return score;
}
1

Narysuj na obrazku jak ty chcesz te tablicę połączyć.
Załóżmy że próbujesz połączyć, tablice 2x3 (zielony prostokąt) oraz 4x5 (niebieski prostokąt)
Rozumiem że wynikiem będzie tablica 6x8 zaś dalej nie rozumiem co chcesz zrobić.

0

Chciałbym je połączyć w ten sposób
screenshot-20210415212514.png

1

Czemu puste pod 9,10 nie zaś pod 3,4?
I co ma być w tych pustych?

0

Jeśli tak będzie prościej to zróbmy jak mówisz. Nie dostałem konkretnie jak mam je połączyć. Jeśli można to do pustych dałbym "-"

1
table polacz (const table &a,const table &b)
{
    table score;
    inicjuj(score,a.cols+b.cols,max(a.rows+b.rows));
    for(int y=0;y<a.rows;++y)
    {
        if(y>=b.rows) continue;
        for(int x=0;x<a.cols;++x) score.data[y][x]=a.data[y][x];
    }
    for(int y=0;y<b.rows;++y)
    {
        if(y>=a.rows) continue;
        for(int x=0;x<b.cols;++x) score.data[y][x+a.cols]=b.data[y][x];
    }
    return score;
}
0

Teraz to wygląda w ten sposób:

tablica polacz (const tablica &tab1,const tablica &tab2)
{
    tablica score;
    inicjuj(score,tab1.cols+tab2.cols,max(tab1.rows,tab2.rows));
    for(int y=0;y<tab1.rows;++y)
    {
        if(y>=tab2.rows) continue;
        for(int x=0;x<tab1.cols;++x) score.data[y][x]=tab1.data[y][x];
    }
    for(int y=0;y<tab2.rows;++y)
    {
        if(y>=tab1.rows) continue;
        for(int x=0;x<tab2.cols;++x) score.data[y][x+tab1.cols]=tab2.data[y][x];
    }
    return score;
}

A pojawiło mi się coś takiego:

screenshot-20210415235723.png

1

Cały projekt jest skopany wszędzie ci się pomerdały wysokość z szarością, bo wszędzie stosujesz inne nazewnictwo.
np:

void inicjuj(tablica &tab, int height, int width)
{
    tab.cols = height; //doprawdy? wysokość to ilość kolumn?
    tab.rows = width;
        for (int x=0; x<tab.cols; ++x)  // w zewnętrznej pętli idziesz po kolumnami? WTF?
        {
            for (int y=0; y<tab.rows; ++y) // drukujesz wszystkie elementy z kolumny `x` w jednym wierszu? WTF?
            {
                cout << tab.data[x][y] << " "; // zamiast numeru kolumn podstawiasz numer wiersza? WTF?
            }
            cout<<endl; // po wydrukowaniu kolumny przechodzisz na następny wiersz? WTF?
0

Wydaje mi się że poprawiłem wszystko chociaż nie rozumiem czemu w wynikowej tabeli pierwsza kolumna w 3 wierszu ma takie cyfry:
screenshot-20210416005119.png

Oto cały kod:

#include <iostream>
#include <cmath>

using namespace std;

struct tablica
{
    int **data;
    int rows;
    int cols;
};

void inicjuj(tablica &tab, int height, int width)
{
    tab.rows = height;
    tab.cols = width;
    tab.data = new int *[tab.rows];
    for(int x=0; x<tab.rows; ++x)
    {
        tab.data[x] = new int[tab.cols];
    }
}

void wypisz(const tablica &tab)
{
    if(tab.cols < 1 && tab.rows < 1)
    {
        cout<< "Pusta tablica";
    }
    else
    {
        for(int x=0; x<tab.rows; ++x)
        {
            for(int y=0; y<tab.cols; ++y)
            {
                cout<< tab.data[x][y]<<" ";
            }
            cout<<endl;
        }
    }
    cout<<endl;
}

void wczytaj(tablica &tab)
{
    if(tab.cols < 1 && tab.rows < 1)
    {
        cout<< "Pusta tablica";
    }
    else
    {
        for(int x=0; x<tab.rows; ++x)
        {
            for(int y=0; y<tab.cols; ++y)
            {
                cout << "Podaj wartosc nr ["<< x+1  << "][" << y+1 << "]" << ": ";
                cin >> tab.data[x][y];
            }
        }
    }
}

void zwolnij(tablica &tab)
{
    for(int r=0;r<tab.rows;++r) delete[] tab.data[r];
    tab.data = NULL;
    tab.cols = 0;
    tab.rows = 0;
}

tablica polacz(const tablica &tab1, const tablica &tab2)
{
    tablica score;
    inicjuj(score, max(tab1.rows,tab2.rows), tab1.cols+tab2.cols);
    for(int x=0; x<tab1.rows; ++x)
    {
        //if(x>=tab2.rows) continue;
        for(int y=0;y<=tab1.cols;++y) score.data[x][y]=tab1.data[x][y];
    }
    for(int x=0;x<tab2.rows;++x)
    {
        //if(x>=tab1.rows) continue;
        for(int y=0;y<tab2.cols;++y) score.data[x][y+tab1.cols]=tab2.data[x][y];
    }
    return score;
}

int main()
{
    tablica mojaTablica1;
    tablica mojaTablica2;

    inicjuj(mojaTablica1, 2, 2);
    inicjuj(mojaTablica2, 3, 3);

    wczytaj(mojaTablica1);
    wczytaj(mojaTablica2);

    tablica duzaTab = polacz(mojaTablica1, mojaTablica2);

    wypisz(mojaTablica1);
    wypisz(mojaTablica2);
    wypisz(duzaTab);

    zwolnij(mojaTablica1);
    zwolnij(mojaTablica2);
    zwolnij(duzaTab);

    wypisz(mojaTablica1);
    wypisz(mojaTablica2);
}

2

Zwykłe śmieci, wyzeruj tablicę przed kopiowaniem.
Ewentualnie:

tablica polacz(const tablica &tab1, const tablica &tab2)
{
    tablica score;
    int rows=max(tab1.rows,tab2.rows);
    inicjuj(score,rows,tab1.cols+tab2.cols);
    for(int r=0;r<rows;++r)
    {
        for(int c=0;c<tab1.cols;++c) score.data[r][c]=r<tab1.rows?tab1.data[r][c]:0;
        for(int c=0;c<tab2.cols;++c) score.data[r][c+tab1.cols]=r<tab2.rows?tab2.data[r][r]:0;
    }
    return score;
}

Na ile widzę wciąż masz pomieszanie z popłataniem, może r jak rows oraz c jak cols będę dla ciebie odpowiedniejsze.

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