Tablouri bidimensionale-matrici
1. Forma matrice este impusă de Dicționarul ortografic, ortoepic și morfologic al limbii române (2005).
2. ^ Forma matrici apare în tratate de specialitate și cursuri universitare, de exemplu: Iacob,
Caius (1957). „VIII.B - Matrici. Grupuri. Spații lineare”. Curs de matematici superioare. București:
Editura Tehnică. pp. 808–851..
Un tablou este o structură omogenă (formată din elemente de acelaşi fel) cu un număr bine
determinat de componente. Tabloul se identifică printr-un singur nume, iar componentele sale se
identifică prin intermediul unui sistem de indici.
Alăturat avem reprezentat un tablou.
Un element al acestuia, ai,j, se găseşte pe linia i şi
coloana j.
Este esenţial de reţinut faptul că toate elementele tabloului
au acelaşi tip.
Este o structură omogenă, compusă din date
organizate pe două niveluri ierarhice.
doi indici, a[i][j], unde i este indicele
Componentele tabloului se pot localiza prin
de linie și j este indicele de coloană.
Declarare
int a[50][100],n,m,i,j;
Am declarat: - o matrice cu maxim 50 de linii şi 100 de coloane,
numerotarea se face de la 0
- n- numarul efectiv de linii;
- m- numarul efectiv de coloane;
- i- contor pentru linie
- j- contor pentru coloane
Obs. Putem numerota liniile şi colonele de la 1, în acest caz adăugăm 1
la numărul maxim de linii şi 1 la numărul maxim coloane.
Un magazin oferă spre vânzare n produse.
Se doreşte să se reţină vânzările lunare, valorice, din fiecare tip de produs.
Putem organiza datele sub formă de tablou astfel:
vom numerota cele n produse cu 1, 2, ..., n; (linii)
lunile le vom numerota cu 1, 2, ..., 12; (coloane)
elementul ai,j semnifică valoarea încasată din vânzarea produsului i în luna j a
anului - prin urmare, elementele tabloului sunt de tip real.
Raspundeti:
Intrebări posibile
a) Dacă magazinul vinde 5 produse, câte elemente are tabloul?
b) Care sunt indicii de adresare în tablou pentru a afla vânzările din produsul 5 în luna
septembrie?
c) Cum se poate calcula suma încasată în luna mai?
d) Ştiind că, din punct de vedere economic, anul este împărţit în patru trimestre şi că fiecare
trimestru are trei luni, cum se poate calcula suma încasărilor din trimestrul patru al anului?
e) Cum putem determina produsul din vânzarea căruia s-a încasat anual suma maximă?
f) Care este luna cu cele mai mari încasări?
Tot aşa, se poate memora, sub formă de tablou, situaţia la învăţătură a celor m elevi ai unei
clase.
Dacă numerotăm elevii cu 1, 2, ..., m şi materiile pe care aceştia le studiază cu 1, 2, ..., n, atunci
ai,j reprezintă media pe care o are elevul i la materia j.
Raspundeti:
Întrebări posibile
a) Dacă în clasă sunt 30 de elevi şi aceştia studiază 8 materii, câte elemente are matricea?
b) Care este materia la care elevii au cele mai bune rezultate?
c) Care este media generală a elevului i?
d) Care este media generală a elevilor unei clase?
Cum citim şi cum afişăm un tablou bidimensional ?
int a[10][9];
În C++, matricea are liniile 0,1,...,9 şi coloanele 0,1,…,8 şi, de exemplu, elementul de pe linia a
treia şi coloana a patra se adresează prin a[2][3].
Uneori, pentru simplitate, vom folosi liniile şi coloanele matricei începând de la 1. În aceste
condiţii se pierde o linie şi o coloană, fiecare de indice 0.
De multe ori nu ştim câte linii şi câte coloane va
trebui să aibă tabloul.
În acest caz, tabloul se declară cu un număr maxim de
linii şi un număr maxim de coloane, în aşa fel încât
acesta să corespundă oricărui set de date de intrare.
Evident, într-un astfel de caz există o risipă de memorie internă,
dar... programul nu se va termina cu eroare.
În figura alăturată, aveţi reprezentat grafic un tablou cu 8 linii şi 8
coloane, din care, într-un anumit caz, utilizăm numai primele 4
linii şi primele 5 coloane.
Programul care-l utilizează va funcţiona corect dacă avem cel mult
8 linii şi cel mult 8 coloane
Declararea unui tablou de memorie de tip matrice (cu două dimensiuni) se face prin
instrucţiunea:
unde precizează tipul elementelor matricei, este identificatorul
matricei, iar şi sunt două constante întregi care specifică numărul de elemente
ale matricei pentru fiecare dimensiune: – numărul de linii, iar – numărul
de coloane.
De exemplu, prin instrucţiunile declarative:
int a[2][4]; float b[3][5];
se declară două matrice: a cu 8 elemente de tip int, care are 2 linii şi 4 coloane, şi
b, cu 15 elemente de tip float, care are 3 linii şi 5 coloane.
Alocarea zonei de memorie pentru o variabilă tablou bidimensional se face în zone de octeți
succesive, conform numărului de elemente din cadrul liniilor.
Şi la declararea unei matrice se pot atribui valori iniţiale elementelor, cu instrucţiunea:
Pentru prelucrarea datelor memorate într-o matrice, referirea la un element al matricei se face
prin construcţia:
unde nume este numele matricei, este numărul de ordine al liniei, iar
este numărul de ordine al coloanei
Elementele sunt situate într-o zona de memorie continuă ( elementele tabloului se află la adrese
succesive).
Vizualizarea in forma dreptunghiulara, matriceala, a unui tablou bidimensional, t,
cu m linii si n coloane va genera configuratia privind accesul la elementele lui.
Un element se poate localiza și prin rangul său, care este numărul lui de ordine
în cadrul tabloului.
Daca, pentru un tablou bidimensional cu m linii si n coloane, continand elemente de un anume
tip si, pentru un i (0≤ i < m) si un j (0 ≤ j < n) fixate, dorim sa stim numarul de ordine al unui
element dintre cele m · n elemente, atunci se face un simplu calcul:
rang_element = i · n + j, unde rang ia valori de la 0 la m · n -1.
123
456
789
1 are rang 0 (linia 0, coloana 0)
2 are rang 1 (linia 0, coloana 1)
3 are rang 2 (linia 0, coloana 2)
4 are rang 3 (linia 1, coloana 0)
Invers, daca se cunoaste rangul elementului si se doreste aflarea perechii (i, j) prin
care se desemneaza coordonatele elementului in cadrul tabloului, atunci:
i ← rang / n, iar j ← rang % n
Tabloul pătratic -caz particular de tablou bidimensional
numărul de linii este egal cu numărul de coloane, adică
În situația în care
m=n se vorbește despre un tablou pătratic sau matrice pătratică.
Într-un tablou pătratic se pot defini grupările de elemente numite
diagonalele structurii – diagonala principală și diagonala secundară,
În aceeași manieră ca și la matematică.
Într-o matrice pătratică numarul de linii= numarul de coloane
(n=m).
Într-o matrice pătratică avem:
Diagonala principala elementele a[i][i], cu i=1,n
sau a[i][i], cu i=0,n-1
Diagonala secundara elementele a[i][n-i+1], i=1,n (i+j=n+1)
sau a[i][n-i-1], i=0,n-1(i+j=n-1)
Diagonala principală grupează elementele de la colțul NV
către colțul SE ale structurii pătratice.
De la elementul t[0][0] la elementul t[n-1][n-1]
Se observă că elementele diagonalei principale au indicele
de linie egal cu indicele de coloană.
Proprietatea este cunoscută din matematică și poate fi exprimată t[i][i].
Diagonala secundară grupează elementele de la colțul NE
către colțul SV ale structurii pătratice.
De la elementul indicat prin t[0][n-1] la elementul t[n-1][0]
Se observă că elementele diagonalei secundare au indicele
de linie egal cu simetricul indicelui de coloană.
Proprietatea poate fi exprimată t[i][n-1-i] .
Diagonala principala elementele:
a[i][i], cu i=1,n
sau a[i][i], cu i=0,n-1
Diagonala secundara elementele:
a[i][n-i+1], i=1,n
sau a[i][n-i-1], i=0,n-1
Zonele determinate de diagonale:
I.
Pe diagonala principală i=j
Sub diagonala principala: i>j
Deasupra diagonalei principale:i<j
II
Deasupra diagonalei secundare: j=n-i+1
Sub diagonala secundara: j>n-i+1
Deasupra diagonalei secundare: j <n-i+1
În matricele pătratice diagonalele delimitează anumite triunghiuri de
elemente:
triunghiul inferior diagonalei principale, respectiv superior;
triunghiul inferior diagonalei secundare, respectiv superior;
triunghiurile de elemente delimitate de ambele diagonale: nord, est, sud și
vest
Vecinii unui element din matrice
Observaţie: În unele probleme ne putem deplasa numai pe linie şi pe coloană, vom avea in acest
caz numai 4 vecini (N, E, S, V)
Se citeşte şi se afişează un tablou. Iniţial se citesc numărul de linii şi de coloane ale tabloului
(m şi n).
include <iostream>
using namespace std;
int main()
{
int m,n,i,j,a[10][9];
cout<<"m=";
cin>>m;
cout<<"n=";
cin>>n;
for (i=0; i<m; i++)
for(j=0; j<n; j++)
{
cout<<"a["<<i+1<<',' <<j+1<<"]=";
cin>>a[i][j];
}
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
return 0;
}
Algoritmi pentru parcurgerea elementelor unei matrice
Parcurgerea elementelor unei matrice se poate face:
de la primul element până la ultimul element,
de la ultimul element până la primul element.
Secvenţa de instrucţiuni pentru parcurgerea elementelor unei matrice de la primul element
la ultimul element este:
int i,j,m,n,a[10][10];
// se declară variabilele i şi j pentru indicele elementului,
// i - numărul liniei şi j - numărul coloanei
// m şi n pentru lungimea logică a matricei (m - numărul de
// linii şi n - numărul de coloane) şi a pentru o matrice cu
// lungimea fizică de 10 linii şi 10 coloane.
cout<<"m= ";
cin>>m; // se citeşte numărul de linii ale matricei
cout<<"n= ";
cin>>n; // se citeşte numărul de coloane ale matricei
for (i=0; i<m; i++) // se parcurg liniile matricei
for (j=0; j<n; j++) //se parcurg coloanele matricei de pe o linie
.....; //instrucţiunea pentru prelucrarea elementului a[i][j]
Secvenţa de instrucţiuni pentru parcurgerea elementelor unei matrice de la ultimul
element la primul element este:
int i,j,m,n,a[10][10];
cout<<"m= ";
cin>>m;
cout<<"n= ";
cin>>n;
for (i=m-1; i>=0; i--) // se parcurg liniile matricei
for (j=n-1; j>=0; j--) //se parcurg coloanele matricei de pe o linie
.....; //instrucţiunea pentru prelucrarea elementului a[i][j]
Parcurgerea unei matrice pe contur:
în sensul acelor de ceasornic (în sens invers trigonometric).(m linii si n coloane)
int i,j,m,n,a[10]10];
..................... //se citesc valorile
elementelor matricei
for (j=0; j<n; j++) cout<<a[0][j]<<" ";
for (i=1; i<m; i++) cout<<a[i][n-1]<<"
";
for (j=n-2; j>=0; j--) cout<<a[m-1]
[j]<<" ";
for (i=m-2; i>0; i--) cout<<a[i][0]<<" ";
în sens trigonometric.
Aplicaţii cu tablouri bidimensionale
Aplicaţia 1. Interschimbare de linii.
Se citeşte un tablou cu m linii şi n coloane.
Se citesc, de asemenea, şi două numere naturale distincte x şi y, cuprinse între 1 şi m.
Se cere să se interschimbe linia x cu linia y.
La început vom afişa tabloul iniţial, apoi pe cel obţinut prin interschimbarea liniilor x şi y.
Exemplu: Considerăm tabloul de mai jos, cu m=3, n=3 şi liniile x=2, y=3:
În urma interschimbării liniilor 2 şi 3 se obţine:
#include <iostream>
using namespace std;
int main()
{
int mat[10][10],m,n,i,j,x,y,man;
cout<<"m=";
cin>>m;
cout<<"n=";
cin>>n;
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
cout<<"mat["<<i+1<<','<<j+1<<"]=";
cin>>mat[i][j];
}
cout<<"x=";
cin>>x;
cout<<"y=";
cin>>y;
cout<<endl;
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
cout<<mat[i][j]<<' ';
cout<<endl;
}
for(j=0; j<n; j++)
{
man=mat[x-1][j];
mat[x-1][j]=mat[y-1][j];
mat[y-1][j]=man;
}
cout<<endl;
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
cout<<mat[i][j]<<' ';
cout<<endl;
}
return 0;
}
Aplicaţia 2: Să se inverseze coloanele unei matrice cu n linii şi m coloane (n≤10, m≤10,) cu
elementele numere întregi.
#include <iostream>
using namespace std;
int main()
{
int n,m,i,j,x,a[10][10];
cout<<"n =";
cin>>n;
cout<<"m =";
cin>>m;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
{
cout<<"a["<<i+1<<","<<j+1<<"]= ";
cin>>a[i][j];
}
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
cout<<endl;
for (i=0; i<n; i++)
for (j=0; j<m/2; j++)
{
x=a[i][j];
a[i][j]=a[i][m-j-1];
a[i][m-j-1]=x;
}
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
Aplicaţia 3: Se citesc de la tastatură elementele unei matrice cu m linii şi n coloane. Elementele
matricei sunt de tip întreg. Să se afişeze maximul dintre elementele matricei şi poziţia primei
apariţii a acestuia (linia şi coloana).
#include <iostream>
using namespace std;
int main()
{
int n,m,i,j,max,a[10][10],nl,nc;
cout<<"n =";
cin>>n;
cout<<"m =";
cin>>m;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
{
cout<<"a["<<i+1<<","<<j+1<<"]= ";
cin>>a[i][j];
}
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
cout<<endl;
max=a[0][0];
nl=0;
nc=0;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
if (a[i][j]>max)
{
max=a[i][j];
nl=i;
nc=j;
}
cout<<"maximul este "<<max<<" si apare prima data "<<endl;
cout<<" in linia "<<nl+1<<" si coloana "<<nc+1<<endl;
return 0;
}
Aplicaţia 4:
Se consideră o matrice a cu m linii şi n coloane, cu elemente numere reale.
Valorile pentru m şi n şi pentru elementele matricei se citesc dintr-un fişier text, unde sunt scrise
astfel: pe primul rând valorile pentru m şi n, iar pe următoarele m rânduri, câte n elemente de pe
fiecare linie a matricei. Numerele sunt separate prin spaţiu.
Să se bordeze matricea cu coloana n+1, ale cărei elemente a[i][n+1] au ca valoare media
aritmetică a celor n elemente din linia i, şi cu linia m+1, ale cărei elemente a[m+1][j] au ca
valoare media aritmetică a celor n elemente din coloana j.
Să se scrie într-un fişier text matricea obţinută
#include <iostream>
using namespace std;
int main()
{
int n,m,i,j;
float max,a[10][10],s;
cout<<"m =";
cin>>m;
cout<<"n =";
cin>>n;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
{
cout<<"a["<<i+1<<","<<j+1<<"]= ";
cin>>a[i][j];
}
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
cout<<endl;
for (i=0; i<m; i++)
{
s=0;
for (j=0; j<n; j++)
s+=a[i][j];
a[i][n]=s/n;
}
n++;
for (i=0; i<n; i++)
{
s=0;
for (j=0; j<m; j++)
s+=a[j][i];
a[m][i]=s/m;
}
m++;
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
return 0;
}
Tema
1. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30)
care determină şi afişează valoarea maxima şi de cate ori apare aceasta în tablou.
2. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30).
Sa se afişeze tabloul obţinut prin înlocuirea tuturor valorilor minime cu valoarea maxima din
tablou.
3. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30).
Să se calculeze procentul elementelor prime din matrice.
4. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30).
Să se calculeze şi să se afişeze ultima cifră a produsului elementelor impare de pe coloanele
pare.
5. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30. Să
se afişeze liniile impare de la stânga la dreapta iar cele pare de la dreapta la stânga.
6. Să se determine dacă într-un tablou bidimensional cu m linii şi n coloane (m, n≤30) care
memorează numere întregi există componente egale cu suma indicilor lor.
7. În fişierul [Link] este memorată o matrice a cu m linii şi n coloane (n≤30) de numere întregi de
cel mult 9 cifre fiecare. Să se genereze două matrice b şi c unde bij memorează suma cifrelor lui
aij iar cij memorează numărul cifrelor lui aij.
8. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30).
Sa se afişeze valoarea minima de pe fiecare linie şi maximul valorilor astfel obţinute.
9. Scrieţi un program care citeşte un tablou bidimensional A cu m linii şi n coloane (m<=30, n<=30).
Să se bordeze matricea cu linia m+1 şi coloana n+1, unde A[m+1,j] reprezintă suma elementelor
de pe coloana j şi A[i, n+1] reprezintă suma elementelor de pe linia i iar A[m+1][n+1] va memora
suma tuturor componentelor.
10. Scrieţi un program care citeşte un tablou bidimensional cu m linii şi n coloane (m<=30, n<=30).
Să se interschimbe valorile de pe linia p cu valorile de pe linia q, unde p şi q se citesc de la
tastatură.