Programowanie i algorytmy

Tablice wielowymiarowe w C++

 

powrót

Inicjacja tablicy dwuwymiarowej

Jako tablicę dwuwymiarową możemy sobie wyobrazić planszę prostokątną składającą się z pewnej liczby wierszy i kolumn (numerowanie zaczynamy od zera). Aby przypisać (pobrać) wartość do danej komórki, należy podać jej obie współrzędne.

Inicjacja tablicy polega na podaniu ilości wierszy i kolumn:

typ_elementów_tablicy nazwa_tablicy [ ilość wierszy ][ ilość kolumn ];

np.:

//stworzenie dwuwymiarowej tablicy liczb całkowitych, w sumie 100 komórek: 10x10.

int tab [ 10 ][ 10 ];

 

Nadanie wartości początkowych tablicy

Wartości początkowe tablicy możemy nadać przy jej deklaracji. Popatrzmy na przykład oparty na tablicy dwuwymiarowej liczb całkowitych:

 

//zauważmy, że mamy trzy wiersze, i dwie kolumny
int tab[3][2] = {{1,3},{4,5},{0,-1}};

 

Przy nadawaniu wartości tablicy można pominąć wartość w pierwszym nawiasie kwadratowym:

 

//wartość pierwszego nawiasu została pominięta
int tab[][2] = {{1,3},{4,5},{0,-1}};

 

Odwoływanie się do komórek w tablicy dwuwymiarowej 

Aby odwołać się do każdej z komórek należy w nawiasach kwadratowych podać numer wiersza i kolumny komórki, do której się odwołujemy, pamiętając o tym, że numerujemy je od zera:

 

int tab[][2] = {{1,3},{4,5},{0,-1}}; //deklaracja i inicjacja tablicy dwuwymiarowej
cout<<tab[2][1]; //wyświetlenie wartości komórki znajdującej się w trzecim wierszu i w drugiej kolumnie (-1)
tab[0][0] = -100; //przypisanie do pierwszej komórki wartości -100

 

Przydzielanie pamięci na tablicę dwuwymiarową

Jeśli wielkość tablicy zależy od pewnych czynników, na przykład podajemy z klawiatury jej wielkość, lub ograniczenia stosu nie pozwalają nam na stworzenie odpowiednio dużej tablicy, to możemy przydzielić pamięć na nią dynamicznie (pobrać pamięć ze sterty):

int **tab, k, w;
  cout<<"Podaj liczbę wierszy i kolumn w tablicy: ";
 
  cin>>w>>k;
 
  tab = new int *[w]; //przydzielenie pamięci na w wierszy
 
  for(int i=0;i<w;i++)
    tab[i] = new int[k]; //przydzielenie dla każdego wiersza po k komórek
 
  //instrukcje własciwe programu
 
  //zwolnienie pamięci
  for(int i=0;i<w;i++)
    delete [] tab[i];
 
  delete [] *tab;
 

 

Warto przy okazji zauważyć, że liczba komórek w każdym wierszu może mieć różną wartość, czyli tablica dwuwymiarowa nie musi być prostokątna:

int **tab, k, w;
  cout<<"Podaj liczbę wierszy: ";
 
  cin>>w;
 
  tab = new int *[w]; //przydzielenie pamięci na w wierszy
 
  for(int i=0;i<w;i++)
  {
    cout<<"Podaj liczbę komórek w wierszu o numerze "<<i<<": ";
    cin>>k;
    tab[i] = new int[k]; //przydzielenie dla każdego wiersza po k komórek
  }
 
  //instrukcje własciwe programu
 
  //zwolnienie pamięci
  for(int i=0;i<w;i++)
    delete [] tab[i];
 
  delete [] *tab;

 

Przykładowe zadanie

Zad. Napisz program, który wykona transpozycję macierzy 4x5. Liczby generujemy losowo z przedziału [-9; 9]. Elementami macierzy są liczby całkowite.

 

Rozwiązanie:

Macierz to obiekt, który doskonale nadaje się do przechowywania w tablicach dwuwymiarowych. Każda macierz składa się z pewnej ilości wierszy i kolumn. Przykładowa macierz spełniająca warunki zadania:

{tex}\begin{bmatrix} 1 & 1 &- 5 & 8 & 2\\ 2 & 2 & 0 & 0 & 5\\ 3 & 3 & 6 & -6 & 4\\2 & 4 & 5 & -9 & -8 \end{bmatrix}{/tex}

 

Transpozycja macierzy polega na zamianie wierszy z kolumnami. Powyższa macierz powinna wyglądać następująco:

 

{tex}\begin{bmatrix} 1 & 2 & 3 & 2\\ 1 & 2 & 3 & 4\\ -5 & 0 & 6 & 5\\8 & 0 & -6 & -9\\2 & 5 & 4 & -8\end{bmatrix}{/tex}

 

#include<iostream>
using namespace std;
 
int main()
{
 
  int tab[4][5]
 
  cout<<"Przed transpozycją:\n ";
 
  for(int i=0;i<4;i++)
  {
    for(int j=0;j<5;j++)
    {
      //wygenerowanie liczb z zakresu [-9; 9]
      tab[i][j]=rand()%19-9; 
      //wyświetlenie wylosowanej liczby
      cout<<tab[i][j]<<" "; 
    }
    cout<<endl;
  }
 
  //transpozycja macierzy
  cout<<"Po transpozycji: "<<endl;
  for(int i=0;i<5;i++)
  {
    for(int j=0;j<4;j++)
      cout<<tab[j][i]<<" ";
 
  cout<<endl;
  }
 
  system("pause");
  return 0;
}

 

Zerowanie tablicy wielowymiarowej

Jeśli chcemy wyzerować tablicę (ustawić wszystkie jej komórki na wartość {tex}0{/tex}, możemy to zrobić przy jej definiowaniu:

int tab[5][5] = {};

 

Taka konstrukcja zadziała tylko przy tworzeniu tablicy. Jeśli chcemy ponownie ją wyzerować musimy posłużyć się pętlami (w przypadku dwuwymiarowej tablicy będą dwie zagnieżdżone pętle):

  int tab[100][23];
 
  for(int i=0;i<100;i++)
    for(int j=0;j<23;j++)
      tab[i][j]=0;
 

 

Jeśli tablicę zadeklarujemy jako globalną, także zostanie wyzerowana:

#include<iostream>
using namespace std;
 
int tab[100][23]; //wszystkie elementy są wyzerowane
 
int main()
{
 
  // ciało funkcji main()
 
  return 0;
}

 

Tablice wielowymiarowe

Tablice o większej liczbie wymiarów rzadko się stosuje. Sposób inicjacji, oraz operowania na tablicach tego typu jest analogiczny jak w przypadku tablic dwuwymiarowych.

Prześledźmy przykład tworzenia tablicy trójwymiarowej:

 

#include<iostream>
#include<cstdlib>
using namespace std;
 
int main()
{
  //deklaracja tablicy trójwymiarowej
  //taka tablica posiada 3*4*5 = 60 komórek
  int tab[3][4][5]; 
  //przypisanie wartości 23 do pierwszej komórki
  tab[0][0][0] = 23; 
 
  cout<<tab[0][0][0]<<endl;
 
  system("pause");
  return 0;
}

 

Odwołując się do komórek tablicy trójwymiarowej, możemy sobie wyobrazić, że odwołujemy się to jednostkowych sześcianów, z których zbudowany jest prostopadłościan. Aby "dostać się" do danego sześcianu, musimy określić jego współrzędne: długość, szerokość oraz wysokość.