Sunteți pe pagina 1din 14

Tipul de date tablou

Tabloul reprezinta o succesiune indexata de date de acelasi tip. Indexarea poate fi facuta:
1) Cu un indice – tabloul se numeste liniar sau vector (sir)
2) Cu 2 indici - se numeste tablou 2- dimensional, sau dreptunghiular, sau matrice
3) Cu 3- indici - tablou 3- dimensional
….
In Pascal se declara un tip tablou in felul urmator:

c11 c12 c13 c14 c21 c22 c23 c24 c31 c32 c33 c34
La tabloul D tot sunt 3*4= 12 elemente. Elementele vor fi:

( )
D [ 1 ] [ 1 ] D [ 1 ] [ 2 ] D [ 1 ] [ 3 ] D[1][4 ]
D= D [ 2 ] [ 1 ] D [ 2 ] [ 2 ] D [ 2 ] [ 3 ] D[2][4 ]
D [ 3 ] [ 1 ] D [ 3 ] [ 2 ] D [ 3 ][ 3 ] D[3][4]

Eficienta tablourilor:
1. Intr-un tablou pot fi pastrate mai multe date cu acelas nume si el poate fi parcurs de
mai multe ori, folosind instructiuni ciclice.
2. Pentru a citi tabloul, a atribui valori elementelor unui tablou, a scrie elementele, a
prelucra elementele tabloului vom folosi instructiuni ciclice.
Tablouri liniare, sau vectori.
Exemplu: var A: array [1..50] of integer;
Ca sa nu citim 50 elemente, putem lua o var n: byte; Ii atribuim valoare, n<=50 si citim
numai n- elemente din tablou. Algoritmul de citire este:
write(‘n=’); readln(n);
For i:=1 to n do begin
Write(‘A[‘, i,’]=’); readln(a[i]);
end;

3. Pentru a scrie elementele tabloului a tot vom folosi o instructiune ciclica, numai ca
vom scrie doar valorile citite intr-o linie, separate prin spatiu:

Ex. writeln(‘elementele tabloului sunt:’);


For i:=1 to n do write(a[i],’ ’);
Writeln;
4. Pentru a parcurge tabloul si a afla suma elementelor, numarul maxim, numarul
minim, cate numere sunt pozitive, cate negative, cate egale cu 0, iar vom folosi o
instructiune ciclica.
Pentru aceasta vom lua var S, max, min: integer; i,n, k1, k2, k3: byte;
s:=0; max:=a[1]; min:=a[1]; k1:=0; k2:=0; k3:=0;
For i:=1 to n do begin s:=s+a[i];
If a[i]>max then max:=a[i];
If a[i]<min then min:=a[i];
If a[i] >0 then inc(k1)
else if a[i]=0 then inc(k2)
else inc(k3);
End;
writeln(‘Suma elementelor S=’,s);
writeln(‘Numarul maxim max=’,max);
writeln(‘numarul minim este min=’, min);
if k1=0 then writeln(‘Nu sunt numere pozitive’)
else writeln(‘numarul de numere pozitive este k1=’,k1);
if k2=0 then writeln(‘Nu sunt numere egale cu 0’)
else writeln(‘numarul de numere egale cu 0 este k2=’,k2);
if k3=0 then writeln(‘Nu sunt numere negative’)
else writeln(‘numarul de numere negative este k3=’,k3);

5. Daca dorim acum sa aflam cate elemente din tablou au valoarea egala cu max si cate
cu min, iar putem parcurge tabloul.
k1:=0; k2:=0;
for i:=1 to n do begin if a[i]=max then inc(k1);
if a[i]=min then inc(k2);
end;
writeln(‘numarul de elemente=max este k1=’,k1);
writeln(‘numarul de elemente=min este k2=’,k2);
6. Pentru a afla de exemplu locul primului element par in tabloul a, ne vom folosi de
instructiune while, pentru nu a parcurge toate elementele. Ex
i:=1;
while (i<=n) and (odd (a[i])) do inc(i);
If i=n+1 then writeln(‘nu sunt elemente pare’)
Else writeln(‘Locul primului element par este=’,i);
Tablouri liniare, sau vectori in C++.
Tabloul reprezinta o succesiune indexata de date de acelasi tip. Indexarea poate fi facuta:
4) Cu un indice – tabloul se numeste liniar sau vector (sir)
5) Cu 2 indici - se numeste tablou 2- dimensional, sau dreptunghiular, sau matrice
6) Cu 3- indici - tablou 3- dimensional

Spre deosebire de limbajul Pascal in C++ tablourile se declara mai simplu si indexarea
deobicei e cu indice natural, ce ia valori 0… n-1 , n – e o constanta, ce va indica ca tabloul
are n-elemente.

De exemplu: int A[20] . Acest tablou va avea elementele:


A[0], A[1], A[2], …. , A[19]
Daca am declarat n<=20 rezulta ca trebuie sa declaram cu un element mai mult int A[21];
Citirea, scrierea parcurgerea vom face-o ca si in Pascal, folosind instructiunea for

Citirea:
cout<<”n=”; cin>>n;
for (i=0; i<=n-1; i++) {cout<<”A[”<<i<<”]=”; cin>>A[i]; }

Scrierea:
cout<<”Avem tabloul”<<endl;
for (i=0; i<=n-1 ; i++) cout<<A[i]<<” ”;
cout<<endl;

Prelucrarea datelor de tip tablou : sum, maxx, minn,…

int sum=0, maxx=A[0]; minn=A[0]; k=0;


for (i=0; i<=n-1; i++) { sum+=A[i]; maxx= max(maxx,A[i]);
minn=min(minn, A[i]);
if (A[i] % 7 == 0) k++;
/* II metoda: if (A[i]>maxx) maxx=A[i];
If(A[i]<minn)minn=A[i]; */
}
Tablori liniare- vectori.
Algoritmi de prelucrare a tablourilor
Fie ca avem tabloul int A[100], cu n- elemente : A[0] A[1] A[2] … A[n-1]

1. Inversarea elementelor unui tablou: Ex. 4 5 6 9 8 7 12 3 4 6 n=10


De scris algoritmul de inversare a tabloului: A[0]= 6 A[1]=4 A[2]=3 … A[9] =4
6 4 3 12 7 8 9 6 5 4
- Vom parcurge tabloul pana la jumatate
- Facem schimbul de valori: swap (A[i], A[n-i-1])
Algoritmul este :

for (i=0; i<=(n-1) /2; i++) swap(A[i], A[n-i-1]);


2. Permutarea ciclica a elementelor cu o pozitie in stanga:
5 6 9 8 7 12 3 4 6 4
x =A[0];
for (i=0; i<=n-2; i++) A[i]= A[i+1];
A[n-1]= x;
3. Permutarea ciclica a elementelor cu o pozitie in dreapta:
6 4 5 6 9 8 7 12 3 4
x =A[n-1];
for (i=n-1; i>=1; i--) A[i]= A[i-1];
A[0]= x;
4. De determinat daca in tabloul A sunt elemente consecutive egale: da/ nu (cu while)
i=0;
while (i<=n-2 && A[i] != A[i+1] ) i++;
if (i==n-1) cout<<”nu sunt consecutive egale”<<endl;
else cout<<”sunt consecutive egale”<<endl;
5. De aflat locul I element egal cu maxi; Presupunem ca am aflat nr. maxi
i=0;
while (i<=n-1 && A[i] != maxi] ) i++;
cout<<i<<endl;
6. Locul I element par

// For( i=0; i<=n-1 && A[i] % 2 ; i++, ;)


i=0;
while (i<=n-1 && A[i] %2) i++;
if (i==n) cout<<”nu sunt numere pare”<<endl;
else cout<<”locul I nr. par i=”<<i<<endl;
Sortarea tablourilor. Metode de sortare.
Metode de sortare
Vom sorta tabloul in ordine:
1. Crescatoare / strict crescatoare
2. Descrescatoare / strict descrescatoare
Definitie 1. Tabloul A[0.. n-1] este in ordine crescatoare, daca
A[i]<=A[i+1], pentru orice i=0.. n-2

Definitie 2. Tabloul A[0.. n-1] este in ordine descrescatoare, daca


A[i]>=A[i+1], pentru orice i=0.. n-2
Definitie 3 Tabloul A[0.. n-1] este in ordine strict crescatoare, daca
A[i]<A[i+1], pentru orice i=0.. n-2
Definitie 4 Tabloul A[0.. n-1] este in ordine strict descrescatoare, daca
A[i]>A[i+1], pentru orice i=0.. n-2

Pentru a determina daca tabloul e in ordine crescatoare, ne folosim de urmatorul algoritm:


i=0;
while (i<=n-2 && A[i]<= A[i+1]) i++;
if (i==n-1) cout<<”tabloul e crescator”;
else cout<<”tabloul nu e crescator”;
Analog descrescator: i=0;
while (i<=n-2 && A[i]>= A[i+1]) i++;
if (i==n-1) cout<<”tabloul e descrescator”;
else cout<<”tabloul nu e descrescator”;
Putem alcatui si functie de tip boolean, care sa returneze valoare true, cand tabloul e
crescator/ descrescator si false in caz contrar:
bool cresc() // pentru cazul crescator
{ i=0;
while (i<=n-2 && A[i]<=A[i+1]) i++;
return (i==n-1);
}

bool cresc() // pentru cazul descrescator


{ i=0;
while (i<=n-2 && A[i]>=A[i+1]) i++;
return (i==n-1);
}
Sunt mai multe metode de sortare:
Metodele de sortare:
1. Selectia
2. Insertia
3. Metoda bulelor
4. Distribuirea
5. Interclasarea
6. Quick Sort (se bazeaza pe Divide et Impera)
7. Merge sort
8. Heap Sort ….
Selectia

Selectia este o metoda de sortare care parcurge secventa de elemente ne sortate, determina
elementul minim, sau maxim si il aduce la inceputul secventei.
metoda I ne optimala: ( face multe schimburi de valori swap(A[i],A[j])

For (i=0; i<=n-2; i++)


For (j=i+1; j<=n-1; j++)
If (A[j]<A[i]) swap(A[i], A[j]);

Selectia metoda II optimala:


Ex sortam crescator: luam variabila int minn; si int k;
Variabila min va afla elementul minim de la i+1 pana la n-1, iar k- va pastra locul unde se
afla elementul minim. Daca k !=i atunci se face doar un singur schim de valori intre
swap(A[i],A[k]).
int minn,k;
for (i=0; i<=n-2; i++)
{ min=A[i]; k=I;
for (j=i+1; j<=n-1; j++)
If (A[j]<minn) {minn= A[j], k=j);}
if (k!=i) swap(A[i], A[k]);
Insertia:
Spre deosebire de selectie, inseria opereaza cu elementele deja aranjate si un element din cele
ne aranjate. Compara si gaseste pozitia si il insereaza.
Pentru aceasta vom lua variabila ajutatoare int x;

Algoritmul de sortare prin insertie:


for ( i=1; i<=n-1; i++)
{ x=A[i]; j=I -1;
while (j>=0 && x<A[j]) { A[j+1]= A[j]; j- - }
A[j+1]=x;
}
Acest algorit efectuiaza permutarea ciclica a elementelot cu o pozitie in dreapta si apoi il
insereaza pe x.

Metoda bulelor:

Spre deosebire de selectie, metoda bulelor compara elementele consecutive A[j] cu


A[j+1] si va face schimb de valori, daca A[j+1]<A[j], in caz ca sorteaza crescator si
A[j+1]>A[j], in caz ca sorteaza descrescator. In rezultatul la o parcurgere elementul maxim,
sau minim se transfera la sfarsit. Efectuand (n-1) parcurgeri, tabloul va fi sortat.

Metoda I
For ( i=1; i<=n-1; i++)
For (j=0; j<=n-2; j++)
If( A[j+1]< A[j]) swap(A[j], A[j+1]); // tabloul se va sorta crescator
N=8 si am efectuat 7 – parcurgeri in cel mai rau caz.
Cum sa optimizam parcurgerile si schimbul de valori?
1. Vom memoriza pozitia unde s-a efectuat ultimul schimb de valori si la urmatoarea
parcurgere vom veni pana la aceasta pozitie
2. Daca am parcurs si nu am efectuat nici un schimb de valori, atunci elementele sunt
aranjate deja in ordine crescatoare si nu mai trebuie sa parcurgem:
Avem nevoie de urmatoarele variabile: bool u; int l, k; k- va fixa pozitia unde el va face
ultimul schimb de valori, l va primi valoarea lui k, iar urmatoarea parcurgere va fi pana la l-
1;

Metoda bulelor II, cea mai optimala:

bool u= true; k=n-1;


while (u) { u=false; l=k;
For (j=0; j<=l -1; j++)
If (A[j+1]<A[j]) {swap(A[j+1], A[j]); k=j; u=true;}
}

III metoda:
For (i=n-1; i>=1; i--)
For (j=0; j=i -1;i++)
If (A[j+1]<A[j]) swap(A[j], A[j+1]);
Interclasarea tablourilor sortate, de ex. descrescator.

Fie A[n] : 9 8 6 5 4 4 3 2 n=8


B[m] : 10 9 8 7 7 5 4 3 2 0 -5 -7 m=12
Trebuie sa obtinem tabloul C[n+m] care sa fie sortat descrescator, fara a sorta el.
Ex.
C[8+12] : 10 9 9 8 8 7 7 6 5 5 4 4 4 3 3 2 2 0 -5 -7
1. Pentru a obtine tabloul C, vom lua variabila int k=-1 , ca contor ciclic. Atunci cand tribuin
element lui C facem in prealabil ++k: C[++k] = valoare; sau k++; C[k]=valoare;
2. Vom parcurge concomitent si tabloul A si tabloul B
3. Determinam care element e mai mare dintre A[i] sau B[j] si pe acela il atribuim lui C[k]
4. Dupa ce se epuizeaza elementele unui tablou vom atribui lui C[k] elementele ramase
5. Vom folosi 3 instructiuni ciclice while … do
i=0; j=0; k=-1;
while (i<=n-1 && j<=m-1)
if (A[i]>=B[j]) { k++; C[k]=A[i]; i++;}
else { k++; C[k]=B[j]; j++;}
while (i<=n-1) { k++; C[k]=A[i]; i++;}
while (j<=m-1) { k++; C[k]=B[j]; j++;}
for (i=0; i<=k; i++) cout<<C[i]<<” “;
cout<<endl;
Tablouri 2-dimensionale (matrici)

Indexarea datelor intr-un tablou 2- dim se face cu doi indici, la matematica valoarea initiala a
indicilor este de la 1, dar totusi se aloca memorie si pentru linia 0 si coloana 0. Vom declara
un tablou 2-dim in felul urmator Ex. <tip> A[8][10]. Tabloul A va contine maximal 8-linii
si 10 – coloane. Automat se aloca memorie si pentru linia 0 si coloana 0 Daca intexarea vom
incepe de la 1, atunci putem avea maxim 7- linii si 9- coloana. La matematica tabloul A[n]
[m] se scrie in felul urmator:

Pentru a citi, a scrie, a parcurge un tablou 2- dimensional se folosesc 2 instructiuni ciclice una
in alta. Ex un for (i=1; i<=n; i++) si in acest for un alt for (j=1; j<=m; j++). Ciclul cu
indicile j se va executa pentru fiecare valoare a lui i. Vom avea (n*m - elemente)
Citirea: cin>>n>>m;
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{ cout<<”A[“<<i<<”][”<<j<<”]=”; cin>>A[i][j]; }
Scrierea: for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{ cout<<setw[5]<<A[i][j];
cout<<endl;
}

De parcurs tabloul A si de aflat suma numerele, numarul maxim, numarul minim:


int S=0, maxi=A[1][1], mini=A[1][1];
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{ S+=A[i][j] ;
maxi=max(maxi,A[i][j]);
mmii=min(mini,A[i][j]);
}
Ex de program: Problema1
1. Citeste n, m
2. Citeste tabloul A
3. Scrie tabloul A, aliniind numerele in coloane
4. Afla si scrie suma- S; nr. maxim maxx;
numarul minim minn; cate numere sunt divizibile cu 3
#include <bits/stdc++.h>
using namespace std;
int A[10] [15], n, m, i, j;
int main()
{ cout<<"n="; cin>>n; // n- indica numarul de linii
cout<<"m="; cin>>m; // m- indica numarul de coloane
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{ cout<<"A["<<i<<"]["<<j<<"]="; cin>>A[i][j];
}
cout<<"avem tabloul 2-dim"<<endl;
for (i=1; i<=n; i++)
{ for (j=1; j<=m; j++)
cout<<setw(5)<<A[i][j];
cout<<endl;
}
int S=0, maxx=A[1][1], minn=A[1][1], k=0;
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{ S+=A[i][j];
maxx=max(maxx, A[i][j]);
minn=min(minn, A[i][j]);
if ( A[i][j] % 5 = =0) k++;
}
cout<<"Suma="<<S<<endl;
cout<<"numarul maxim="<<maxx<<endl;
cout<<"numarul minim="<<minn<<endl;
if (k) cout<<"numarul de nr divizibile cu 5 este k="<<k<<endl;
else cout<<"nu sunt numere divizibile cu 5"<<endl;
return 0;
}
Sortarea liniilor / coloanelor unui tablou 2- dim
De exemplu: De sortat liniile unui tablou 2-dim in ordine crescatoare prin insertie:

For (i=1; i<=n; i++)


for (k=2; k<=m; k++)
{ x=A[i][k];j=k-1;
while (j>=1 && x<A[i][j]) {A[i][j+1]=A[i][j]; j-- ;}
A[i][j+1]=x;
}
cout<<"Liniile tabloului sortate crescator sunt:"<<endl;
for (i=1; i<=n; i++)
{ for (j=1; j<=m; j++)
cout<<setw(5)<<A[i][j];
cout<<endl;
}
Observam ca avem nevoie de 3 instructiuni ciclice:
1. for cu I parcurge liniile
2. for cu j si while sorteaza numerele in linie
Analog se sorteaza si coloanele

Tablouri (matrici) patrate: m=n.


La tablourile patrate nr. liniilor coincide cu numarul coloanelor
Tabloul patrat are 2 diagonale:
1. Diagonala principala, unde j=i si contine elementele A[1][1] A[2][2] ….A[n][n]
2. Diagonala secundara, unde j=n+1-i si contine elementele A[1][n] A[2][n-1] … A[n][1]
Daca n>=3, atunci diagonalele impart elementele tabloului 2- dim in 4 sectoare:
I sector : (j>I && j<n+1-i)
II sector : (j<I && j<n+1-i)
III sector : (j<i && j>n+1-i)
IV sector : (j>i && j>n+1-i)

S-ar putea să vă placă și