Tablouri multidimensionale
Un tablou multidimensional este un tablou
indexat cu mai mulți indici. Dacă un vector are
un singur indice (v[i]), un tablou bidimensional
are doi (a[i][j]), iar unul tridimensional are trei
(a[i][j][k]).
Cu alte cuvinte, este extensia naturală a vectorilor la mai multe dimensiuni.
De la vector la tablou multidimensional
Vector (1D)
int v[101];Accesăm elementele cu un singur indice:
v[1]v[2]v[i]
Matrice (2D)
int a[101][101];Accesăm elementele cu doi indici:
a[1][1]a[2][3]a[i][j]
Acesta este cazul cel mai frecvent și l-ai văzut deja la matrici.
Tablou tridimensional (3D)
int b[11][21][31];Accesăm elementele cu trei indici:
b[1][1][1]b[2][3][4]b[i][j][k]
Ne putem imagina un tablou 3D ca pe o colecție de straturi, unde fiecare strat este o matrice.
Cum arată un tablou tridimensional?
Să presupunem că avem 2 straturi, fiecare cu
3 linii și 4 coloane.
Stratul 1
1 2 3 4
5 6 7 8
9 1 2 3Stratul 2
4 5 6 7
8 9 1 2
3 4 5 6Putem spune că:
b[1][1][1] = 1b[1][2][3] = 7b[2][3][4] = 6
În notația b[i][j][k]:
i= stratulj= liniak= coloana
Ideea-cheie: o matrice este doar un tablou bidimensional. Un tablou tridimensional este un „teanc de matrici”.
Declararea unui tablou multidimensional
Bidimensional
int a[101][101];Tridimensional
int b[11][101][101];Acesta poate memora, de exemplu, cel mult:
10straturi100linii pe fiecare strat100coloane pe fiecare strat
Avem nevoie și de dimensiunile efective:
int p, n, m; // p = straturi, n = linii, m = coloaneCitirea unui tablou tridimensional
Dacă primim p, n, m,
apoi valorile pentru toate elementele, folosim 3 bucle
imbricate.
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int b[11][101][101];
int p, n, m;
int main()
{
fin >> p >> n >> m;
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
fin >> b[i][j][k];
return 0;
}date.in:
2 2 3
1 2 3
4 5 6
7 8 9
10 11 12Aici avem:
2straturi2linii3coloane
Afișarea unui tablou tridimensional
De obicei afișăm pe straturi:
for (int i = 1; i <= p; i++) {
fout << "Stratul " << i << ":\n";
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= m; k++)
fout << b[i][j][k] << " ";
fout << "\n";
}
}Parcurgerea completă
La un tablou cu d dimensiuni, avem în general
nevoie de d bucle.
Pentru 2D
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
// procesăm a[i][j]Pentru 3D
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
// procesăm b[i][j][k]Suma tuturor elementelor
int suma = 0;
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
suma = suma + b[i][j][k];
fout << suma;Maximul dintr-un tablou 3D
int maxim = b[1][1][1];
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
if (b[i][j][k] > maxim)
maxim = b[i][j][k];
fout << maxim;Suma pe fiecare strat
Fiecare strat este, practic, o matrice.
for (int i = 1; i <= p; i++) {
int suma = 0;
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
suma = suma + b[i][j][k];
fout << "Stratul " << i << ": " << suma << "\n";
}Suma pe o linie fixă din toate straturile
De exemplu, vrem suma elementelor de pe linia x
din toate straturile:
int x;
fin >> x;
int suma = 0;
for (int i = 1; i <= p; i++)
for (int k = 1; k <= m; k++)
suma = suma + b[i][x][k];
fout << suma;Numărarea elementelor cu o proprietate
Câte elemente pare sunt în tot tabloul?
int cnt = 0;
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
if (b[i][j][k] % 2 == 0)
cnt++;
fout << cnt;Matricea este un caz particular
Un tablou bidimensional este exact o matrice. De aceea:
- la 2D vorbim despre linii și coloane
- la 3D vorbim despre straturi, linii și coloane
- la 4D și mai sus, ideea este aceeași, doar că apar mai mulți indici
În practică, la concursuri apar cel mai des:
- vectori (1D)
- matrici (2D)
- mai rar tablouri 3D
Exemplu complet
Citim un tablou 3D și afișăm suma fiecărui strat și maximul global.
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int b[11][101][101];
int p, n, m;
int main()
{
fin >> p >> n >> m;
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
fin >> b[i][j][k];
int maxim = b[1][1][1];
for (int i = 1; i <= p; i++) {
int suma = 0;
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++) {
suma = suma + b[i][j][k];
if (b[i][j][k] > maxim)
maxim = b[i][j][k];
}
fout << "Stratul " << i << ": suma = " << suma << "\n";
}
fout << "Maximul: " << maxim << "\n";
return 0;
}date.in:
2 2 3
1 2 3
4 5 6
7 8 9
10 11 12date.out:
Stratul 1: suma = 21
Stratul 2: suma = 57
Maximul: 12Memorie și limitări
Un tablou multidimensional ocupă multă memorie.
De exemplu:
int b[11][101][101];are aproximativ 11 * 101 * 101 ≈ 112000
elemente.
Dacă fiecare int ocupă 4 bytes, atunci memoria
folosită este de aproximativ:
112000 * 4 ≈ 448000 bytesadică aproximativ 448 KB.
La dimensiuni mari, tablourile multidimensionale se declară global, nu local.
Greșeli frecvente
1. Ordinea indicilor este încurcată
b[j][i][k] // GREȘIT dacă ordinea este [strat][linie][coloana]
b[i][j][k] // CORECTMereu trebuie să știm clar ce reprezintă fiecare indice.
2. Numărul de bucle nu corespunde dimensiunilor
Pentru un tablou 3D avem nevoie de 3 bucle, nu de 2.
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= m; k++)
fin >> b[i][j][k];3. Dimensiunile sunt declarate prea mici
Dacă p <= 10, n <= 100,
m <= 100, declarăm ceva de forma:
int b[11][101][101];ca să putem indexa de la 1.
4. Tabloul este declarat local și ocupă prea mult
int main() {
int b[50][500][500]; // PERICOL!
}Tablourile mari se declară global.
5. Confuzia dintre „dimensiune” și „indice”
În:
int b[11][101][101];11,101,101sunt dimensiunile maximei,j,ksunt indicii cu care accesăm elementele
Ce să reții
- Un tablou multidimensional are 2 sau mai mulți indici.
- Matricea este un tablou bidimensional.
- Un tablou 3D se poate vedea ca un set de straturi, fiecare fiind o matrice.
- Pentru un tablou cu
ddimensiuni folosim, de regulă,dbucle imbricate. - Accesul se face cu notații de forma
a[i][j],b[i][j][k]. - Tablourile mari se declară global.
- În practică, cele mai importante sunt tablourile 2D și 3D.