Sunteți pe pagina 1din 27

Tabloul cu doua dimensiuni- MATRICEA

STRUCTURI DE DATE
1. IMPLEMENTAREA STRUCTURILOR DE DATE Memoria interna a calculatorului este organizata ca un ansamblu de celule separate care au adrese consecutive. Intr-o astfel de celula sau intr-un grup de celule adiacente, se poate memora o data elementara. In acelasi mod este organizata si memoria externa: un ansamblu de locatii de memorare numite sectoare, care au adrese consecutive. In cadrul unei aplicatii pot sa apara multe date de acelasi tip. De exemplu, o firma vrea sa prelucreze cu ajutorul calculatorului situatia vanzarilor. Informatia prelucrata va fi organizata logic intr-un tabel in care fiecare produs reprezinta un rand si fiecare zi dintr-o anumita perioada (saptamana, luna, an) reprezinta o coloana. Acest mod de organizare permite o analiza rapida a informatiei si usureaza munca de obtinere a informatiilor statistice (volumul vanzarilor dintr-o zi, volumul vanzarilor pentru un produs intr-o anumita perioada, cel mai bine vandut produs intr-o anumita perioada, etc.). Organizarea logica a informatiilor in exteriorul calculatorului trebuie sa se regaseasca si in interiorul lui, in modul in care sunt organizate efectiv datele in memoria calculatorului. Asadar, colectia de date sau structura de date reprezinta o metoda de aranjare a datelor care sunt dependente unele de altele in cadrul unei aplicatii. Structura de date este o colectie de date intre elementele careia se defineste un anumit tip de relatie care determina metodele de localizare si prelucrare a datelor. Asadar, structura de date este o metoda de aranjare a datelor care sunt dependente unele de altele in cadrul unei aplicatii. Ea este o colectie de elemente pentru care s-a precizat: Tipul elementelor, Proprietatile de organizare a elementelor, Regulile de acces la elemente. Componentele unei structure de date pot fi: Date elementare, Structure de date. O structura de date este o entitate de sine statatoare. Ea poate fi identificata printr-un nume, iar componentele ei isi mentin atributele. Fiecarei structure de date ii este specific un anumit mechanism de identificare si de selectie a componentelor colectiei de date. Componentele structurii de date pot fi identificate prin : Indentificatorul (numele) componentei, sau Pozitia pe care o ocupa componenta in cadrul structurii. Structurile de date pot fi clasificate dupa diferite criterii:

1. In functie de tipul componentelor structurii: a. Structuri omogene (componentele sunt de acelasi tip) b. Structuri neomogene (componentele sunt de tipuri diferite) 2. in functie de modul de localizare a componentelor structurii: a. structuri cu acces direct (o componenta poate fi localizata fara sa se tina cont de celelalte component ale structurii), b. structuri cu acces secvential (o componenta poate fi localizata numai daca se parcurg componentele care o preced in structura); 3. in functie de tipul de memorie in care sunt create: a. structuri interne (in memoria interna) b. structuri externe (in memoria externa) 4. in functie de timpul de utilizare : a. structuri de date temporare (pot fi organizate atat in memoria interna, cat si in cea externa), b. structuri de date permanente (pot fi organizate numai in memoria externa); 5. in functie de stabilitatea structurii: a. structuri dinamice (in timpul existentei, in urma executarii unor procese, isi modifica numarul de componente si relatiile dintre ele), b. structuri statice (nu isi modifica in timpul existentei numarul de componente si relatiile dintre ele). Asupra unei structuri de date se pot executa mai multe operatii care pot afecta valorile componentelor structurii si/sau structura de date: 1. Crearea, prin care se realizeaza structura de date in forma initiala, pe suportul de memorie utilizat. 2. Consultarea, prin care se realizeaza accesul la componentele structurii in vederea prelucrarii valorilor acestora si a extragerii de informatii. 3. Actualizarea, prin care se schimba starea structurii astfel incat ea sa reflecte corect valoarea componentelor la un moment dat. Actualizarea se face prin trei operatii : adaugarea unor noi componente, stergerea unor componente si modificarea valorii componentelor. 4. Sortarea, prin care se rearanjeaza componentele structurii in functie de anumite criterii de ordonare aplicate valorilor componentelor. 5. Copierea, prin care se realizeaza o imagine identical a structurii, pe acelasi suport sau pe suporturi diferite de memorare. 6. Mutarea, prin care se transfera structura, pe acelasi suport, la o alta adresa, sau pe un suport de memorare diferit. 7. Redenumirea, prin care se schimba numele structurii.

8. Divizarea, prin care se realizeaza doua sau mai multe structuri dintr-o structura de baza. 9. Reuniunea (concatenarea), prin care se realizeaza o singura structura de date, prin combinarea a doua sau mai multe structuri de date de acelasi tip. 10. Stergerea, prin care se distruge structura de date. Implementarea unei structuri de date presupune: Definirea structurii din punct de vedere logic, adica definirea componentelor, a relatiei dintre componente si a operatiilor care pot actiona asupra structurii. Definirea structurii din punct de vedere fizic, adica a modului in care va fi reprezentata structura pe suportul de memorare. Se pot folosi mai multe tipuri de structuri de date. Tipul de structura de date defineste apartenenta structurii de date la o anumita familie de structuri carora le corespunde acelasi mod de organizare logica, acelasi model de reprezentare fizica si care pot fi supuse acelorasi operatii. Dintre tipurile de structuri de date fac parte: Tablourile de memorie; Fisierele.

2.TABLOURILE DE MEMORIE S presupunem c o aplicaie trebuie s ordoneze cresctor un ir oarecare de 20 de numere. Cele 20 de numere sunt date de intrare i, la primul pas al algoritmului, vor fi introduse in memoria intern a calculatorului. La primul pas numerele vor fi prelucrate i rearanjate conform criteriului de ordonare precizat, dup care, la al treilea pas, vor fi furnizate utilizatorului sub forma de date de ieire. n memoria intern ele vor fi nregistrate ntr-o structur de date de tip tablou de memorie. Tabloul de memorie(array) este o structur de date intern format dintr-o mulime ordonat de elemente, ordonarea fcndu-se cu un ansamblu de indici. Tabloul de memorie se va identifica dup un nume (a), iar fiecare element al sudup numele tabloului i numrul de ordine. n cazul exemplului prezentat, cele 20 de numere se vor pstra ntr-o zon continu de memorie intern, care va conine 20 de celule de memorare. Presupunnd c datele elementare care compun structura sunt de tip int i ocup fiecare dintre ele cte doi octei, nseamn c ntreaga structur va ocupa 40 de octei. n loc s se atribuie datelor 20 de nume, se va atribui un singur nume ntregii structuri, iar fiecare dat se va regsi, n cadru structurii, dupa numrul de ordine. Presupunnd c adresa de la care ncepe structura de date este 500, acesta reprezint adresa primului element, adresa

ultimului elementfiind 538. Dup prelucrarea datelor de intrare prin procesul de sortare, se va obine un nou tablou de memorie(b) care conine datele de ieire. Fiecare element al structurii de date se identific dup numele tabloului i poziia din tablou. Astfel, elementul a3 este al treilea element din tabloul a, iar data memorat are valoare 1. Elementul b2 este al doilea element din tabloul b, iar data memorat are valoarea 4. Se observ c, de la nceput, trebuie s se precizeze cte elemente va conine structura de date pentru ca sistemul s-i aloce zona de memorie corespunztoare. n exemplu, se va preciza c cele dou tablouri de memorie vor avea fiecare cte 20 de elemente de tip ntreg pe 2 octei, iar sistemul le va aloca fiecruia dintre ele o zon de memorie de 40 de octei, aa cum aloc zon de memorie intern i datelor elementare in funcie de tipul lor. Rezult c, n timpul prelucrrii, structura de date de tip tablou nu permite modificarea lungimii structurii, deoarece prin adugarea de noi elemente se iese din spaiul de memorare alocat. Deci, tabloul de memorie este o structur de date static .

date de intrare 4 500 10 502

Memoria interna
1 ... 25

date de ieire
1 4 5

prelucra re
... 57

S considerm o alt aplicaie. Sunt cinci contoare pentru energia electric, ce se citesc trimestrial, i se nregistreaz ntr-un tabel consumul trimestrial(n mii de kWh). Tabelul va avea 4 linii, corespunztoare celor 4 trimestre, i 5 coloane, corespunztor celor cinci contoare. Aceste date de intrare pot fi prelucrate prin diferite procese, obinndu-se informaii despre: media consumului trimestrial pe un singur contor sau pe toate contoarele, cel mai mare consum trimestrial, cel mai mic

consum trimestrial, contorul cu cel mai mic consum etc. n vederea prelucrrii, datele de intrare vor fi organizate ntr-o structur de date de tip bidimensional cu patru linii i cinci coloane, cu numele c. Identificare unui element din tablou se va face de data acesta nu printr-un numr de ordine, ci prin numrul liniei i numrul coloanei. Astfel, elementul c2,3 este elementul din linia 2 i coloana 3 i, n exemplul nostru, are valoarea 32.

contoarele

1 2 3 4 5

1 43 12 43 45 76

2 23 123 123 67 78

3 43 32 13 56 76

4 12 87 68 76 78

5 34 67 68 67 123

trimestrele

Elementul din linia 2 i coloana 3


Memoria intern nu are o structur matriceal. Ea este format din locaii de memorare care au adrese consecutive. Din acest cauz, structura dreptunghiular a tabelului trebuie simulat. Spaiul de memorare alocat tabelului va fi o zon continu, de 40 de octei, n care se vor memora datele din tabel, linie cu linie. Numrul de ordine m al elementului din linia i i coloana j dintr-un tablou cu n coloane este: m=n*(i-1)+j. La definirea unui tablou de memorie trebuie specificate: numele tabloului de memorie; dimensiunea tabloului de memorie; numrul de elemente pe fiecare dimensiune.

Metoda de memorare a elementelor tabloului, n ordine, unul dup altul, ntr-o zon continu de memorie, n locaii cu aceeai dimensiune, este folosit pentru identificarea elementelor structurii i se realizeaz printr-un ansamblu de indici. Numrul de indici (k) folosit pentru identificarea elementelor determin dimensiunea tabloului. Astfel: pentru k=1 structura este un tablou unidimensional numit vector; pentru k=2 structura este un tablou bidimensional numit matrice. n primul exemplu, s-au folosit cele dou tablouri de memorie cu numele a i b, cu o singur dimensiune i cu 20 de elemente. n al doilea exemplu s-a folosit tabloul cu numele c, cu dou dimensiuni, cu 4 elemente pe o dimensiune (4 linii) i cinci elemente pe cealalt dimensiune (5 coloane). i n cel de al doilea caz, tabloul are tot 20 de elemente. Chiar dac, din punct de vedere al memoriei interne, spaiul de memorare alocat este tot sub forma unui bloc continuu de 40 de octei, cele dou tipuri de tablouri(cu o dimensiune i cu doua dimensiuni) difer ntre ele prin modul n care pot fi identificate elementele structurii. Identificarea unui element al tabloului se face prin numele tabloului i valorile indicilor dup toate dimensiunile. De exemplu, a 6 nseamn elementul 6 din tabloul a, iar c2,4 nseamn elementul de pe linia 2 i coloana 4 din tabloul c. Tablourile de memorie se pot folosi pentru a crea colecii de date care vor fi prelucrate de algoritmi. S considerm o problem clasic, i anume problema celor apte poduri ale oraului Knigsberg. Cele apte poduri peste rul Pregel leag cele patru sectoare ale oraului. Problema const n a stabili un traseu prin care un vizitator s parcurg toate cele patru sectoare ale oraului(A,B,C i D), ntorcnd-se n punctul de unde a plecat, trecnd peste fiecare pod o singur dat. Nu are importan c s-a demonstrat matematic c problema nu are soluii. Ceea ce ne intereseaz este modul n care pot fi furnizate aceste date algoritmului prin care trebuie s se gseasc soluia traseului. Modul n care podurile leag cele patru sectoare ale oraului poate fi reprezentat prin urmtoarea diagram:

B D

Acest informaie, prezentat acum sub form de diagram, poate fi reprezentat n memoria intern sub forma unui tablou bidimensional R, numit matricea podurilor. El are patru linii i patru coloane, care corespund celor patru sectoare ale oraului. Elementului R(i,j) al matricei va conine numrul de poduri care leag sectorul i de sectorul j. Reprezentarea informaiilor sub forma unei structuri de date de tip matrice va permite generalizarea problemei, va furniza o reprezentare simpl a datelor de

intrare i va da posibilitatea dezvoltrii unui algoritm matematic pentru rezolvarea problemei. Elementele matricei podurilor vor conine date numerice ntregi.

A B C D

A 0 2 2 1

B 2 0 0 1

C 2 0 0 1

D 1 1 1 0

Aadar, tabloul este o zon continu de memorie intern creia i se atribuie un nume i care permite memorarea mai multor date de acelai tip. Aceste date pot fi tratate ca un tot unitar sau ca date elementare indepentente . Tabloul de date este o structur de date omogen, acces direct, intern, temporar, static i liniar. Aadar, implementarea unui tabel de memorie se face: Din punct de vedere logic. Tabloul de memorie este o structur de date omogen, cu elemente de acelai tip. Este o structur liniar n care fiecare element, cu excepia ultimului element, are un succesor unic, localizarea unui element n cadrul structurii fcndu-se cu ajutorul unui sistem de indici. Din punct de vedere fizic. Tabloului de memorie i se aloc o zon continu de memorie, de dimensiune fix, care este mprit n locaii de aceeai dimensiune. n fiecare locaie se memoreaz un element al tabloului. Dimensiunea unei locaii este dat de tipul de dat memorat. Localizarea unui element al tabloului se face prin calcularea adresei elementului fa de un element de referin care este adresa tabloului, adic adresa primului element. Fa de operaiile enumerate n general pentru structurile de date, n cazul tablourilor de memorie apar urmtoarele caracteristici: Tabloul de memorie nu poate fi ters, deoarece el este o structur static temporar. La terminarea aplicaiei, zona de memorie alocat lui este eliberat i atribuit altei aplicaii; Tabloul de memorie nu poate fi mutat. Operaia nu are sens, deoarece adresa de memorie intern la care se construiete tabloul este stabilit de sistemul de operare, i nu de utilizator; Nu exist operaia de redenumire.

3. IMPLEMENTAREA TABLOURILOR DE MEMORIE N LIMBAJUL C++ Operatia de creare a unei structuri de date de tip tablou de memorie presupune: 1. Declararea tabloului de memorie pentru a i se aloca spaiu de memorie. Prin acest operaie, trebuie furnizate urmtoarele informaii: numele tabloului care va fi folosit n expresii pentru a-l identifica; tipul elementelor tabloului;

dimensiunea tabloului pentru a preciza numrul de indici folosii pentru localizarea elementelor; numrul de elemente ale tabloului pentru a se cunoate spaiul de memorie care trebuie alocat tabelului. 2. Atribuirea de valori elementelor tabloului, care se poate face prin mai multe metode: prin iniializarea tabloului de memorie, la declararea lui; prin introducerea valorilor de la tastatur; prin preluarea valorilor dintr-o alt structur de date; prin generarea valorilor folosind un algoritm de calcul al lor.

TABLOUL CU DOUA DIMENSIUNI - MATRICEA


Declararea unui tablou de memorie de tip matrice(cu dou dimensiuni) se face prin instruciunea: tip_dat nume [nr_1][nr_2]; unde tip_dat precizeaz tipul elementelor matricei, nume este identificatorul matricei, iar nr_1 i nr_2 sunt dou constante ntregi care specific numrul de elemente ale matricei pentru fiecare dimensiune; nr_1 numrul de linii, iar nr_2 numrul de coloane. De exemplu, prin instruciunile declarative: int a[2][4]; i 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. i la declararea unei matrice se pot atibui valori iniiale elementelor, cu instruciunea: tip_dat nume [nr_1][nr_2]={list_valori}; unde valorile din list se vor atribui elementelor innd cont de faptul c memorarea lor n zona alocat matricei se face linie dup linie. De exemplu, prin instruciunea declarativ: int a[2] [4]={1,2,3,4,5,6,7,8}; sau int a[2][4]={{1,2,3,4}{1,2,3,4}}; se declar o matrice cu valori iniiale, pentru elementele:

Indicele coloanei

Indicele liniei i

0 1

1 5

2 6

3 7

4 8

Pentru prelucrarea datelor memorate ntr-o matrice, referirea la un element al matricei se face prin construcia: nume [indice_1][indice_2]; unde numele matricei, indice_1 este numrul de ordine al liniei, iar indice_2 este numrul de ordine al coloanei. Deoarece adresa matricei este i adresa primului element, iar indicii reprezint deplasarea elementului fa de adresa matricei, numerotarea indicilor se face pornind de la 0, iar 0<=indice_1<n i 0<=indice_2<m, unde n reprezint numrul de linii i m numrul de coloane ale matricei, precizate la declararea ei. De exemplu, a[1][2] reprezint elementul din linia a 2-a i coloana a 3-a din matricea a, i are valoarea 7. Tabloul de memorie fiind o structur de date statistic, la declararea lui i se aloc o zon fix de memorie. Lungimea tabloului de memorie reprezint numrul de elemente ale tabloului. La declararea tabloului este posibil s nu se cunoasc numrul de elemente care vor fi prelucrate la fiecare execuie a programului. n prelucrarea tabloului de memorie se folosesc dou lungimi: Lungimea fizic. Reprezint numrul de elemente stabilit la declararea tabloului. Este numrul maxim de elemente care pot fi stocate n spaiul de memorie rezervat tabloului. Lungimea logic. Reprezint numrul de elemente care vor fi prelucrate la execuia programului. Este mai mic sau cel mult egal cu lungimea fizic(numrul maxim de elemente). Lungimea logic se comunic n timpul execuiei programului, de la tastatur. Ea reprezint numrul de elemente ale vectorului, respectiv numrul de linii i numrul de coloane ale matricei.

1. OPERATII CU MATRICI De multe ori suntem tentati sa spunem ca informatica este doar o materie si ne propunem sa invatam doar ceea ce se regaseste in paginile manualului de informatica.Ceea ce nu se gaseste in acesta reprezinta indrumarea catre aplicatii care sa nu tina neaparat de informatica.Voi prezenta in continuare principalele operatii cu matrice, dublate de un program scris pentru limbajul C++, pentru exemplificare.

a.) Citirea matricei

Putem face aceasta citire utilizand un tablou bidimensional. Valorile elementelor le vom citi pozitie cu pozitie, utilizand doua instructiuni for. #include <iostream.h> int main() { int n,m,a[100][100],i,j; cin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=m;j++) cin>>a[i][j]; //Pentru verificare afisam si matricea retinuta for(i=1;i<=n;i++){ for(j=1;j<=m;j++) cout<<a[i][j]<<' '; cout<<endl; } return 0; } Citirea de mai sus este rareori utilizata si doar de cei incepatori in ale informaticii. Sa presupunem ca avem de scris un program mai complicat , cu operatii dificile cu matrici.Dorim sa testam programul pentruu o matrice de 5 linii si 5 coloane.Introducem cele 25 elemente, programul nu functioneaza corect...Mai facem ceva corectari, iar introducem cele 25 elemente, iar nu functioneza corect, apare frustrarea..... Pentru a evita cazul de mai sus utilizam o citire speciala, dintr-un fisier extern. Cum functioneaza ? In folderul in din care rulati BC.EXE, de obicei C:\BORLANDC\BIN\, creati un fisier de tip text cu numele matrice.txt( numele nu este obligatoriu dar va va ajuta sa va aduceti aminte de el ).Pe prima linie scrieti numarul de linii si numarul de coloane, exact cum le scriati cand utilizati modul de citire de mai sus, apoi, pe urmatoarele n linii veti scrie cele m coloane. Un exemplu concret: //Citirea nr. de linii (n) si de coloane (m)

matrice.txt 55

Obsevati ca puteti citi elementele si insirate unul dupa altul, insa nu veti mai gasi cu usurinta coordonatele 10

15604 12365 04893 15630 15478

fiecaruia.

Programul acum va include fstream.h in loc de iostream.h.Puteti folosi in continuare cin si cout numai ca acum aveti acces si la ifstream sau ofstream. Pentru exemplificare, dorim sa afisam matricea citia din matrice.txt in alt fisier text, rezult.txt. Mai jos veti regasi acelasi program dar acum el utilizeaza citirea din fisier. #include <fstream.h> ifstream fin("matrice.txt"); ofstream fout("rezult.txt"); int main() { int n,m,a[100][100],i,j; fin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=m;j++) fin>>a[i][j]; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) fout<<a[i][j]<<' '; fout<<endl; } return 0; } NOTA.Nu este nevoie sa creati fisierul rezult.txt.Acesta va fi creat automat de program. Acestea fiind cunoscute, putem trece mai departe si vom vedea alte operatii cu matrice. De fiecare data vom utiliza citirea din fisier.

b.) Adunarea matricelor

11

Vom prezenta aici doar cazul particular de adunare a doua matrice. Pentru n matrice puteti folosi un tablou tridimensional. #include <fstream.h> #include <conio.h> ifstream fin("matrice.txt"); ofstream fout("rezult.txt"); int main() { int a[100][100],b[100][100],na,ma,nb,mb,i,j; fin>>na>>ma>>nb>>mb; for(i=1;i<=na;i++) for(j=1;j<=ma;j++) fin>>a[i][j]; for(i=1;i<=nb;i++) for(j=1;j<=mb;j++) fin>>b[i][j]; //Suma nu este posibila decat daca na=nb si ma=mb if(na==nb&&ma==mb) for(i=1;i<=na;i++) { for(j=1;j<=ma;j++) fout<<a[i][j]+b[i][j]<< ' '; fout<<endl; } else cout<<"Adunarea nu este posibila !"; return 0; }

c.) Inmultirea matricelor Incepand de la acest capitol aveti nevoie de ceva cunostinte de matematica pentru rezolvarea problemelor. De aceea nu voi insista cu explicatiile. Doua matrici nu se pot inmulti decat daca numarul coloane al primei matrice este egal cu numarul de linii al celei de-a doua matrice. Matricea produs va avea numarul de linii al primei matrice si numarul de coloane al matricei a doua.

12

#include <fstream.h> #include <conio.h> ofstream g("rezultat.txt"); ifstream f("matrice.txt"); int main() { int a[50][50],b[50][50],c[50][60],l1,c1,l2,c2,sum,i,j,k; f>>l1>>c1>>l2>>c2; if(c1!=l2) g<<"Inmultirea nu este posibila!"<<endl; else { for(i=1;i<=l1;i++) for(j=1;j<=c1;j++) f>>a[i][j]; for(i=1;i<=l2;i++)for(j=1;j<=c2;j++) f>>b[i][j]; cout<<endl; for(i=1;i<=l1;i++) for(j=1;j<=c2;j++) { sum=0; for(k=1;k<=l2;k++) {sum+=(a[i][k]*b[k][j]); c[i][j]=sum;} } for(i=1;i<=l1;i++) { for(j=1;j<=c2;j++) g<<c[i][j]<<' '; g<<endl; }} return 0; }

Observati ca programul calculeaza doar produse de matrice cu elemente numere naturale.Pentru a putea lucra cu numere din Q aveti nevoie sa stabiliti tipul variabilelor de tip FLOAT ( float a de exemplu in loc de int a).

2. ALGORITMI PENTRU PARCURGEREA UNEI MATRICE 13

Parcurgerea unei matrice se poate face: de la primul element pn la ultimul element de la ultimul element pn la primul element Secvena de instruciuni pentru parcurgerea elementelor unei matrice de la primul element la ultimul element este: int i, j, n, m, a[10][10]; // se declar variabilele i i j pentru indicele elementului, // i numrul liniei i j numrul coloanei // n i m lungimea logic a matricei (n numrul de linii i m numrul de coloane) i a // pentru o matrice cu lungimea fizic de 10 linii i 10 coloane. cout<<n= ; cin>>n; // se citete numrul de linii ale matricei cout<<m= ; cin>>m; // se citete numrul de coloane ale matricei for (i=0;i<n;i++) //se parcurg liniile matricei for (j=0;j<=m;j++) //se parcurg coloanele matricei pe o linie ............................; // instruciunea pentru prelucrarea elementului a[i][j] Secvena de instruciuni pentru parcurgerea elementelor unei matrice de la ultimul element la primul element este: int i, j, n, m, a[10][10]; cout<<n= ; cin>>n; cout<<m= ; cin>>m; for (i=n-1;i>=0;i--) // se parcurg liniile matricei for (j=m-1;j>=0;j--) // se parcurg coloanele matricei de pe o linie ............................; // instruciunea pentru prelucrarea elementului a[i][j]

3. ALGORITMI PENTRU CAUTAREA UNUI ELEMENT INTR-O MATRICE Acest algoritm gsete primul element din tablou a crui valoare este o valoare precizat x, n vederea prelucrrii acestui element prin una dintre operaiile: modificarea valorii lui; tergerea elementului din tablou; inserarea unui element dup acest element sau naintea lui; consultarea elementului n vederea efecturii unor calcule. Secvena de instruciuni pentru cutarea elementului ntr-o matrice este: int i=0, j=0, n, m, , x, a[10][10]; 14

cout<<n= ; cin>>n; cout<<m= ; cin>>m; cout<<x= ; cin>>x; ............................; // se creeaz matricea // se parcurge matricea linie cu linie, iar pe fiecare linie se parcurg coloanele pn se gsete // elementul sau se termin de parcurs toate liniile matricei i=0; j=0; while (i<n && a[i][j]!=x) if (j = = n-1) {j=0; i++;} else j++; if (i!=n) cout<<S-a gsit elemental n linia <<i+1<<, coloana <<j+1; else cout<<Nu s-a gsit elementul;

APLICATII

Enunul problemei 1: S se calculeze suma elementelor de pe diagonala principal a unei matrice ptrate, de dimensiune n (n10). Elementele matricei sunt numere ntregi. O matrice ptratic este o matrice n care numrul liniilor este egal cu numrul coloanelor. Elementele de pe diagonala principal au cei doi indici egali (numrul liniei este egal cu numrul coloanei). Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int n, i, j, s=0, a[10][10]; cout<<n= ; cin>>n; for (i=0;i<n;i++) // se parcurge matricea pentru creare

15

for (j=0;j<n;j++) {cout<<"a["<<i<<"]"<<"["<<j<<"]="; cin>>a[i][j];} for (i=0;i<n;i++) // se parcurge diagonala principal { j=i; s+=a[i][j];} cout<<suma= <<s; getch(); } Enunul problemei 2: S se verifice dac o matrice ptrat de dimensiune n (n10) are urmtoarea proprietate: elementele de pe diagonala secundar au valoarea 1, iar restul elementelor au valoarea 0. Elementele matricei sunt numere ntregi. Elementele de pe diagonala secundar au suma indicilor egal cu n-1 (i+j=n-1). Se va folosi o variabil x, care va avea valoarea 1 dac matricea are proprietatea specificat (valoarea logic True), i valoarea 0 dac matricea nu are proprietatea specificat (valoarea logic False). Variabila x se iniializeaz cu 1 (presupunem c matricea are proprietatea specificat). Deoarece, pentru a determina proprietatea matricei, nu trebuie parcurse toate elementele, n cazul n care se gsete un element care nu ndeplinete condiia din proprietate parcurgerea matricei nu se va mai face cu o instruciune for, ci cu o instruciune while. Se vor parcurge coloanele unei linii prin incrementarea indicelui j, dup care se va trece la linia urmtoare, prin incrementarea indicelui i i iniializarea cu 0 a indicelui j. Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int n, i, j, x=1, a[10][10]; cout<<n= ; cin>>n; for (i=0;i<n;i++) for (j=0;j<n;j++) { cout<<"a["<<i<<"]"<<"["<<j<<"]="; cin>>a[i][j];} i=0; j=0; while (i<n && x) {if (i+j = = n-1) { if (a[i][j] != 1) x=0; } else if (a[i][j]!= 0) x=0; if (j = = n-1) { j=0; i++; } else j++; } if (x) cout<<Matricea are proprietile specificate; else cout<<Matricea nu are proprietile specificate; getch(); }

16

Enunul problemei 3: S se inverseze coloanele unei matrice cu n linii si m coloane (n10,m10) cu elementele numere ntregi. Vom folosi algoritmul de inversare a unui vector n el nsui, pentru fiecare linie a matricei. Rezolvare: #include<iostream.h> #include<conio.h> void 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<<"]"<<"["<<j<<"]="; cin>>a[i][j]; } 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; } getch(); } Enunul problemei 4: Se citete un tablou cu m linii si 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 se va afia tabloul iniial, apoi pe cel obinut prin interschimbarea liniilor x i y. Pentru a interschimba coninutul a dou variabile se utilizeaz o a treia, de manevr. De aceast dat, se interschimb dou linii. Am fi tentai ca manevra s fie un vector cu n componente. ns observm c se poate folosi ca manevr o singur variabil de acelai tip cu cel al componentelor de baz ale tabloului. Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int mat[10][10], m, n, i, j, x, y, man; cout<<n= ; cin>>n; cout<<m= ; cin>>m; for (i=0;i<m;i++) for (j=0;j<n;j++) { cout<<"a["<<i<<"]"<<"["<<j<<"]="; cin>>mat[i][j]; } cout<<x= ; cin>>x;

17

cout<<y= ; cin>>y; cout<<endln; 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; } getch(); } Enunul problemei 5: Se citete un tablou cu n linii si n coloane. Se cere s se afieze elementele tabloului n ordinea rezultat prin parcurgerea acestuia n spiral, ncepnd cu primul element din linia 1, n sensul acelor de ceas. Exemplu: 1 2 3 4 5 6 7 8 9

Elementele se vor afia n ordinea: 1 2 3 6 9 8 7 4 5. Pentru a putea rezolva problema, privim tabloul ca pe un amsamblu alctuit din mai multe dreptunghiuri concentrice: * * * * * * * * * * * * * * * * * * * * * * * * *

Tabloul de mai sus este un amsamblu format din trei dreptunghiuri concentrice ultimul are un singur element i nu a putut fi reprezentat. Dup ce stabilim numrul de ptrate, afim elementele aflate pe fiecare latur a fiecrui ptrat n ordinea cerut, avnd grij ca elementele aflate n coluri s nu fie afiate de dou ori.

Rezolvare:

18

#include<iostream.h> #include<conio.h> void main( ) { int mat[10][10], n, i, j, k; cout<<n= ; cin>>n; for (i=1; i<=n; i++) for (j=1; j<=n; j++) { cout<<mat [<<i<< ][<<j<<]=; cin>>mat [i] [j]; } for (k=1; k<=n/2+1; k++) { for(i=k; i<=n-k+1; i++) cout<<mat [k] [i] <<endl; for ( i=k+1; i<=n-k+1; i++) cout<<mat[i][n-k+1]<<endl; for (i=n-k; i>=k; i--) cout<<mat[n-k+1][i]<<endl; for (i=n-k; i>=k+1;i--) cout<<mat[i][k]<<endl; } getch(); } Enunul problemei 6: Pe o tabl cu n linii i m coloane (n, m numere naturale, 1 n,m30), sunt plasate pe unele poziii jetoane cu litere, conform unui joc corect de , iar SCRABBLE. tiind c vocalele au cte un punct iar consoanele cte dou, stabilii valoarea total a cuvintelor de pe tabl. Valorile n i m i configuraia tablei se citesc din fiierul tabla.txt, conform exemplului (locurile goale de pe tabl sunt memorate sub forma unor caractere punct). Exemplu:

Pentru datele de intrare: 3 5 D.SAU ALT I . ..A.. se afieaz 20 (DA=3, STA=5, ALTI=6, SAU=4, AI=2) Cutarea cuvintelor pe tabl i cumularea punctelor lor este, de obicei, prima soluie la care ne gndim. Algoritmul corespunztor acestei soluii pare ns destul de complicat. Simpla parcurgere a matricei de caractere i adunarea valorilor corespunztoare literelor nu este o strategie bun, deoarece se pierde punctajul literelor care apar ntr-un cuvnt pe orizontal i unul pe vertical i care ar trebui luate de dou ori n calcul. De aceea, vom analiza n plus, pentru fiecare liter, dac ea face parte dintr-un singur cuvnt (are litere vecine doar pe orizontal sau doar pe vertical) i se puncteaz obinuit, sau face parte din dou cuvinte (are litere vecine i pe orizontal i pe vertical) i atunci se puncteaz dublu.

19

Rezolvare: #include<fstream.h> #include<conio.h> char a[31][31]; int n, m, i, j, dir, p, pt; ifstream f(tabla.txt); void main() { f>>n>>m; for (i=1; i<=n; i++) for (j=1; j<=m; j++) f>>a[i][j]; pt=0; for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (a[i][j]!=.) { if (a[i][j] == A|| a[i][j] == E || a[i][j] == I || a[i][j] == O || a[i][j] == U ) p=1; else p=2; dir=0; if (i>1 && a[i-1][j]!= . || i<n && a[i+1][j]!=.) dir++; if (j>1 && a[i][j-1]!= . || j<n && a[i][j+1]!=.) dir++; pt+=p*dir; } cout<<pt; getch(); } Enunul problemei 7: Scriei un program care construiete n memorie o matrice patratic cu n linii i n coloane format numai din valori 1 i 2 astfel nct elementele de pe diagonala principal i cea secundar s fie egale cu 1, iar restul elementelor din matrice s fie egale cu 2. Valoarea lui n (numr natural 2<n<23) se citete de la tastatur, iar matricea se va afia pe ecran, cte o linie a matricei pe cte o linie a ecranului, cu cte un spaiu ntre elementele fiecrei linii(ca in exemplu). Exemplu: pentru n=5 se construiete n memorie i se afieaz matricea: 1 2 2 2 1 2 1 2 1 2 2 2 1 2 2 2 1 2 1 2 1 2 2 2 1

Rezolvare:

20

#include<iostream.h> #include<conio.h> void main( ) { int mat[23][23], n, i, j; cout<<n= ; cin>>n; for (i=1; i<=n; i++) for (j=1; j<=n; j++) { a[i][j]=2; if ((i==j)||(i+j==n+1)) a[i][j]=1; } for (i=1; i<=n; i++) { for (j=1; j<=n; j++) cout<<a[i][j]<< ; cout<<endl; } getch(); }

Enunul problemei 8: Scriei un program care citete de la tastatur un numr natural n (2n24) i construiete n memorie o matrice cu n linii i n coloane al crei elemente vor primi valori dup cum urmeaz: - elementele aflate pe diagonala principal vor primi valoarea 0; - elementele de pe prima coloan, cu excepia celui aflat pe coloana principal vor primi valoarea n; - elementele de pe a doua coloan, cu excepia celui aflat pe coloana principal vor primi valoarea n-1; - elementele de pe ultima coloan, cu excepia celui aflat pe coloana principal vor primi valoarea 1; Programul va afia matricea astfel construit pe ecran, cte o linie a matricei pe cte o linie a ecranului cu cte un spaiu ntre elementele fiecrei linii(ca n exemplu): Exemplu: pentru n=4 se va afia matricea alturat: 0 4 4 4 3 0 3 3 2 2 0 2 1 1 1 0

Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int n,a[24][24],i,j; cout<<n=; cin>>n; for (i=1; i<=n; i++) for (j=1; j<=n; j++)

21

if(i==j) a[i][j]=0; else a[i][j]=n+1-j; for (i=1; i<=n; i++) { for (j=1; j<=n; j++) cout<<a[i][j]<< ; cout<<endl; } getch(); } Enunul problemei 9: Scrieti programul C++ care citete de la tastatur un numr natural n (n 20), construiete n memorie i afieaz pe ecran, matricea cu n linii i n coloane, primele n 2 numere naturale nenule, pare, care nu sunt divizibile cu 3. Exemplu: pentru n=4 se va construi i afia matricea alturat: 2 4 8 10 14 16 20 22 26 28 32 34 38 40 44 46

Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int n,a[20][20],i,j,k; cout<<n=; cin>>n; k=2; for (i=1; i<=n; i++) for (j=1; j<=n; j++) {a[i][j]=k; k=k+2; if(k%3==0) k=k+2; } for (i=1; i<=n; i++) { for (j=1; j<=n; j++) cout<<a[i][j]<< ; cout<<endl; } getch(); }

22

Enunul problemei 10: Scriei un program C++ care citete de la tastatur un numr natural n (2<n<=15) i construiete n memorie o matrice a cu n linii i n coloane n care orice element aflat pe prima linie sau pe prima coloan are valoarea 1 i oricare alt element a ij din matrice este egal cu suma a dou elemente din matrice, primul aflat pe linia i i pe coloana j-1 iar cel de-al doilea pe coloana j i pe linia i-1. Matricea va fi afiat pe ecran, linie cu linie, numerele de pe aceeai linie fiind separate prin cte un spaiu. Exemplu: pentru n=4, se obine matricea alturat: 1 1 1 1 1 2 3 4 1 3 6 10 1 4 10 20 Rezolvare: #include<iostream.h> #include<conio.h> void main( ) { int n,a[15][15],i,j; cout<<n=; cin>>n; for (i=1; i<=n; i++) for (j=1; j<=n; j++) if((i==1)||(j==1)) a[i][j]=1; else a[i][j]=a[i-1][j]+a[i][j-1]; for (i=1; i<=n; i++) { for (j=1; j<=n; j++) cout<<a[i][j]<< ; cout<<endl; } getch(); }

23

Manual de utilizare
Pentru a facilita utilizarea informatiilor din aceasta lucrare am creat un site ajutator. Pentru deschiderea acestuia dati dublu click pe fisierul home.html

24

Dupa accesarea acestui fisier se va deschide prima pagina a site-ului. Aceasta prezinta continutul site-ului si meniul de accesare a paginilor acestuia.

meniu Prin apasarea unui buton al meniului se va deschide pagina ce ii corespunde acestuia, identificabila dupa descrierea din meniu, respectiv, pentru apasarea butonului teorie se va deschide pagina site-ului ce contine notiunile teoretice, apasarea butonului programe va deschide pagina site-ului ce contine programele executabile iar apasarea butonului contact se va deschide o pagina din interiorul careia, prin apasarea adresei de mail se va deschide un program pentru redactat email-uri si veti putea trimite o scrisoare electronica autorului site-ului.

25

Pagina Teorie

26

Pagina Programe

Pagina Contact

IV.BIBLIOGRAFIE: 1. Totul despre C si C++, Dr. Kris Jamsa Lars Klander, Editura TEORA, 2005 2. Bazele programarii in C++, Doina Logofatu, Editura Polirom, 2004 3. Informatica varianta C++, Tudor Sorin, Editura L&S Informat, 2000 4. C++, George Mateescu, Editura Petrion, 2003 5. Manual de programare in C++, Stefan Prata, Editura TEORA, 2004

27