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 (indeksowanie rozpoczynamy od zera). Aby przypisać lub 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ład 1

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:

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

 

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

 

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

 

#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;
	}

	return 0;
}

Zerowanie tablicy wielowymiarowej

Jeśli chcemy wyzerować tablicę (ustawić wszystkie jej komórki na wartość $$0$$, 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>
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;

	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ść.