Sunteți pe pagina 1din 13

STIVA

Definitie
Stiva este o structura de date, cu valori de acelasi tip, in care adaugarea (operatia PUSH) si extragerea de elemente (operatia POP) se realizeaza la varf.

Corelare
Cu termenul STIVA ne-am mai intalnit la expresia stiva de lemne, insa imaginea sugerata este una lipsita de ordine. Un cuvant care explica mai bine structura stivei, este cuvantul TEANC. Apare clar ideea ca elementele se suprapun unul altuia, in ordine. Un exemplu de folosire a ideii de stiva este construirea oglinditului unui numar natural. Fie n un numar natural. Sa se creeze numarul n2, numarul oglinda al lui n. (n=1972=> n2=2791). Ideea este de a lua cate o cifra de la sfarsitul lui n (POP) si a o adauga la sfarsitul lui n2 (PUSH). Observam ca atat n , cat si n2, se comporta ca si stive. n2=0; do {cif=n%10; //elementul din varful stivei N n2=n2*10+cif; // PUSH in N2 n=n/10; //POP din N } while (n!=0) //verific daca stiva N este vida cout<<n2;

Implementare
Din punct de vedere al implementarii, pentru reprezentarea in memorie a unei stive, putem folosi vectorul. Declararea unei stive vide: int stiva[100], ns=0; Operatia PUSH: cresc numarul de elemente; folosesc prima pozitie neocupata; ns++;cin>>stiva[ns]; Operatia POP: daca exista elemente in stiva, elimin elementul din varf (practic nu sterg elementul, ci doar il ignor) if (ns>0) ns;

L14. Conversia unui numar din baza 10 in baza B


Un numar NB scris in baza B are cifre cu valori intre 0 si B-1. Pentru a obtine reprezentarea numarului N10 in baza B, trebuie sa realizam un sir de impartiri repetate la B. Fie N10=2490 si B=8 2490 impartit la 8 produce catul 311 si restul 2.

311 impartit la 8 produce catul 38 si restul 7 38 impartit la 8 produce catul 4 si restul 6 4 impartit la 8 produce catul 0 si restul 4 Luam resturile in ordine inversa si obtinem NB=4672. Algoritmul de mai jos urmareste exact acest tip de calcul. Se observa ca pentru constructia lui NB trebuie sa lipim fiecare rest in fata numarului NB. citeste N10; NB=0; p10=1; cat timp(N10!=0) { NB=NB+P10*(N10%B); P10=P10*10; N=N/B; } scrie NB.

L13. Conversia unui numar din baza B in baza 10 02OCT


Un numar NB scris in baza B are cifre cu valori intre 0 si B-1. Problema noastra este sa determinam ce numar N10 ii corespunde lui NB pentru baza 10. Pentru aceasta sa observam urmatorul exemplu. Un numar in baza 10, N10=2490 poate fi scris si in forma canonica, adica N10=2*10^3+4*10^2+9*10^1+0*10^0. Fie NB=4672 scris in baza B=8. Pentru a converti NB in baza 10 trebuie sa il scriem in forma canonica. N10=4*8^3+6*8^2+7*8^1+2*8^0. Dupa calcule se obtine valoarea N10=2490.

Practic trebuie sa calculam o suma de produse a cifrelor din NB cu puteri ale bazei. Vom folosi algoritmul de prelucrare a cifrelor unui numar (NB). citeste NB, B; N10=0; PB=1; executa{ N10=N10+(NB%10)*PB; PB=PB*B; NB=NB/10; }cat timp (NB!=0); scrie N10;

L12. Sirul lui Fibonacci


02OCT
Sirul lui Fibonacci este 1, 1, 2, 3, 5, 8, 13, 21, 34, . si are legatura cu celebrul numar de aur. Se observa ca sirul incepe cu valorile 1 si 1 , dupa care, fiecare noua valoare se obtine prin adunarea ultimelor doua valori: F(1)=1 F(2)=1 F(n)=F(n-1)+F(n-2)

Pentru noi problema este de a determina al N-lea termen din sir. Daca N=1 sau N=2, raspunsul este simplu, 1. In restul cazurilor trebuie ca avand mereu ultimile valori A si B, sa calculam noua valoare C=A+B. citeste N; A=1;B=1; daca (N<=2) atunci scrie 1; altfel {pentru i=3,N executa {//calculam noua valoare C=A+B; //pregatim noua pereche A=B;B=C} scrie B;}

L11. Cmmdc. Cmmmc


28SEP
C.m.m.d.c. este acronimul (prima litera de la fiecare cuvant) de la cel mai mare divizor comun si se aplica pentru doua numere naturale. Problema. Fie doua numere naturale A si B. Sa se determine cel mai mare divizor comun a lui A si B. Sa citim iar. Practic trebuie sa determin un numar natural care sa fie divizor atat pentru A cat si pentru B. Daca sunt mai multe numere in aceasta situatie, atunci il aleg pe cel mai mare. Ceea ce ma duce cu gandul la

Varianta 1.

citeste A, B; cmmdc=0; pentru D=1 pana la A executa daca (A%D==0 si B%D==0 ) atunci cmmdc=D; scrie cmmdc; Practic, cmmdc-ul va fi cel mult unul dintre numere. As putea sa fiu prevazator si sa aleg ca limita superioara pe cel mai mic dintre A si B. Si conditia de numitor comun se poate rescrie A%D +B%D==0.

Varianta 2.
citeste A,B min=A; daca (min>B) atunci min=B; pentru D=1 pana la min executa daca (A%D +B%D==0) atunci cmmdc=D; scrie cmmdc;

Varianta 3.
Problema nu e noua, Euclid (cca 325 265 .Hr.!!!!!) s-a gandit si el la acelasi lucru si a gasit o solutie.

OBS. M-am gandit de multe ori cum sa explic elevilor ce anume l-a facut pe Euclid sa se gandeasca la problema cmmdc si mi-am imaginat urmatorul scenariu: Euclid avea o camera de latime A si lungime B pe care sotia lui vroia sa o acopere cu placi patrate de gresie. Pentru a-si impresiona prietenele, placile trebuiau sa acopere integral suprafata camerei si sa fi cat mai mari. Cum a rezolvat Euclid problema? Practic trebuie desenat un caroiaj cu patrate de latura CMMDC. Daca D este divizorul comun a lui A si B, atunci estista A2 si B2 asa incat: A=D*A2 B=D*B2 si deduce ca si diferenta acestor numere are acelasi divizor comun A-B=D*(A2-B2)

Practic, in lenea lui de a calcula cmmdc(A,B), Euclid propune mereu o pereche mai mica (A -B, B) daca A>B sau (A, B-A) daca B>A. Deci, cmmdc(A, B) este (A-B, B) daca A>B (A, B-A) daca B>A A daca A==B

Se observa ca in primele doua cazuri trebuie sa reluam algoritmul, ceea ce ne duce cu gandul la urmatoarea secventa: citeste A,B cat timp (A!=B) executa daca (A>B) atunci A=A-B; altfel B=B-A; scrie A;

Varianta 4.
Deci varianta 3 e de acum 2000 de ani! Intre timp, s-a mai facut o varianta. Daca A=23456 si B=89 ar trebui sa se efectueze o multime de scaderi a lui B din A. Scaderi repetate, pana nu se mai poate scadea pe B din A! Asta este o impartire si ce ramane in A este restul. In consecinta, pe cel mai mare il vom transforma in restul impartirii. Cand ne oprim? Ne vom opri cand A sau B vor fi nule, ceea ce inseamna ca cealalta valoare, nenula, va fi CMMDC.

citeste A,B; cat timp (A*B!=0) executa //daca nici unul nu e nul. daca (A>B) atunci A=A%B; altfel B=B%A; scrie A+B; //afisez valoarea nenula Varianta 5. Desi varianta 4 e o solutie respectabila, inca nu e de ajuns. Practic, la fiecare iteratie se executa 2 teste cel din CAT TIMP si cel din DACA. Varianta urmatoare foloseste aceeasi idee de mai sus dar elimina unul din teste. citeste A,B; cat timp (B!=0) executa {R=A%B; A=B; B=R;} //se iese cand B este nul=> scrie A; Analiza variantelor Evident, ultima varianta este cea mai buna. Am explicat deja ratiunile prin care s-a trecut de la o varianta la alta. In vederea examenului de bacalaureat va trebuie toate variantele, indeosebi ultima pentru momentul cand va trebui sa programati.

Calculul CMMMC
Pentru calculul matematic a cmmdc pentru doua numere A si B, se realizeaza descompunerea in factori primi si apoi se considera termenii comuni, la puterea cea mai mica. Pentru calculul matematic a cmmmc pentru doua numere A si B, se realizeaza descompunerea in factori primi si apoi se considera termenii comuni si necomuni, la puterea cea mai mare. Practic daca as scrie produsul A*B ca inmultire intre descompunerile lor, as observa ca toti termenii existenti sunt fie parte a CMMDC, fie parte a CMMMC. De aici apare si relatia A*B=CMMDC(A,B)*CMMMC(A,B). Practic ne vom folosi de CMMMC(A,B)=A*B/CMMDC(A,B). citeste A,B A2=A; B2=B; //salvez separat datele initiale //calculez CMMDC cat timp (B!=0) {R=A%B; A=B; B=R;} //afisez CMMMC scrie CMMMC este , A2*B2/A.

L7.2. Care instructiune repetitiva este mai buna? 28SEP


Desi sunteti tentati sa alegeti trebuie sa stit ca ambele instructiuni au aceeasi capacitate. Toata problema este sa verificati in algoritmul dumneavoastra daca trebuie sau nu efectuat un test inainte de executarea instructiunii/instructiunilor de repetat.

Simularea instructiunii CAT TIMP EXECUTA cu EXECUTA CAT TIMP. Instructiunea CAT TIMP EXECUTA intai testeaza si apoi executa; daca comparam secventele de executie observam ca la CAT TIMP EXECUTA intai apare un test/conditie. si apoi este identica cu EXECUTA CAT TIMP; nu ramane decat sa folosim o instructiune de test pentru aceasta conditie;

cat timp (exp_logica) executa instructiune;

daca (exp_logica) atunciexecuta instructiune cat timp (exp_logica)

Observati ca pentru transformarea unei instructiuni cat timp in una executa cat timp, nu trebuie dacat sa identificati conditia si secventa care se repeta; apoi copiati corespunzator in sablon. Simularea instructiunii EXECUTA CAT TIMP cu CAT TIMP EXECUTA .

executa instructiune cat timp (exp_logica);

instructiune;cat timp (exp_logica) executa instructiune;

Simularea instructiunii REPETA PANA CAND cu EXECUTA CAT TIMP.

repeta instructiune pana cand (exp_logica);

executa instructiune cat timp!(exp_logica)

Simularea instructiunii PENTRU cu CAT TIMP EXECUTA .

pentru i<-A pana la B cu pasul C executa instructiune.

i <- A;cat timp (i<=B) executa {instructiune; i<i+C};

L10. Algoritmi fundamentali. Divizibilitate. N este prim? 05MAR


Divizibilitate
Problema. Pentru un N dat, care sunt divizorii lui N? Multimea divizorilor lui N este cuprinsa intre valorile 1 si N. Un numar D este divizor al lui N daca N se imparte exact la D. Pentru noi, impartirea exacta inseamna ca restul impartirii lui N la D este zero. Trebuie sa cautam acele valori intre 1 si N la care N se imparte exact. Vom aifsa si vom numara aceste valori.

natural N, D, NR; NR=0;

citeste N; pentru D=1, N executa daca (N%D==0) atunci { scrie D; NR=NR+1} scrie NR;
Cu numarul de divizori putem stabili daca numarul N este prim.

daca (NR==2) atunci scrie N, " este prim!"

Este N numar prim?


Problema. Fie N un numar natural. Este N numar prim? Conform matematicii un numar N este prim daca are drept divizori pe 1 si pe N. Varianta 1. Ideea este sa realizam cat mai putine teste, astfel incat algoritmul sa se incheie mai repede D=2; cat timp (D<=N-1 si N%D!=0) executa D=D+1; daca (N%D==0) atunci scrie divizibil altfel scrie prim Am redus doua teste : nu mai testam cazul D=1 si D=N. De asemenea, profitam de situatia in care gasim primul divizor pentru a iesi din repetitie. Totusi, pentru cazul in care numarul ar fi prim, inca se executa N-2 pasi. Varianta 2. Numarul 2 este cel mai mic potential divizor. Deduc ca numarul N/2 este cel mai mare potential divizor. D=2; cat timp (D<=N/2 si N%D!=0) executa D=D+1; daca (N%D==0) atunci scrie divizibil altfel scrie prim

In aceasta varianta se executa, in cel mai rau caz, N/2 operatii. Super! Am redus munca la jumatate! Se poate mai bine? Varianta 3. Sa cercetam, in continuare, perechile de potential divizori: 2 cu N/2, 3 cu N/3, 4 cu N/4, . Observ ca pe masura ce primul termen creste, al doilea scade. Deduc ca, la un moment dat cei doi termeni pot fi egali. Adica ar putea fi un element X astfel incat N==X*X sa fie adevarat! In consecinta X=radical(N) . Deci ultima pereche care ar trebui studiata este cea cu radical (N). D=2; cat timp (D<=radical(N) si N%D!=0) executa D=D+1; daca (N%D==0) atunci scrie divizibil altfel scrie prim Este cert ca radical(N)<N/2. Iata ca am obtinut un numar mai mic de operatii. Sa cercetam cat de eficienti sunt algoritmii nostri. Numarul N=611953 este prim, spun unii. varianta 1 va executa maxim 611951 pasi varianta 2 va executa maxim 305 976 pasi

varianta 3 va executa maxim 782 pasi!!!!!!!

E ceva, nu?

Varianta 4. Si inca mai merge daca (N==2) atunci scrie prim altfel daca (nN%2==0 ) atunci scrie divizibil altfel { o D=3; o cat timp (D<=radical(N) si N%D!=0) executa D=D+2; o daca (N%D==0) atunci scrie divizibil o altfel scrie prim } Algoritmul de mai sus verifica daca N este 2 si elimina din discutie numerele pare. Pentru ca majoritatea numerelor prime sunt impare, parcurg numai valorile impare si le intreb daca nu cumva sunt divizori pentru N. Varianta 4 va efectua maxim 390 pasi pentru N=611953.

L9. Algoritmi fundamentali. Siruri de numere 05MAR


Pentru a prelucra un sir de numere trebuie sa stim fie numarul de valori in discutie (sir cu numar cunoscut de valori), fie sa avem o valoare care sa marcheze sfarsitul sirului (de obicei zero).

Prelucrarea unui sir cu numar cunoscut de valori


De vreme ce stim cate valori vor fi in sir (prelucrarea va fi retetat de un numar cunoscut de ori) putem folosi instructiunea FOR/PENTRU.

natural x, n, i; citeste N pentru i=1,N executa

citeste X; //prelucrez X

........ }

Prelucrarea unui sir cu un numar necunoscut de valori (care se incheie cu zero)


Valoarea zero nu face parte din sir si nu trebuie prelucrata. Nu stim exact cand primim valoarea zero (care marcheaza sfarsitul sirului), motiv pentru care la fiecare citire trebuie sa verificam daca s-a citit zero sau nu.Daca valoarea citita nu este zero avem de realizar prelucrarea ceruta de problema si o noua citire.

citeste x; cat timp (x!=0) { //prelucrez valorea X ......... //trec la valoarea urmatoare citeste X }

Probleme
1. 2. 3. 4. 5. Sa se calculeze suma/produsul valorilor din sir Sa se determine valoarea minima/maxima dintre valorile citite. O valoare data Y se gaseste in sir? De cate ori apare o valoare data Y? Presupunand ca sirul reprezinta coeficientii uni polinom ( dati incepand cu gradul cel mai mic), calculati valoarea polinomului intr-un punct Y.

L8. Algoritmi fundamentali. Prelucrarea cifrelor unui numar natural 05MAR


Fie N un numar natural. Avem nevoie sa prelucram pe rand cifrele unui numar natural.

In prelucrarea cifrelor numarului, cel mai usor ajungem la ultima cifra (N%10) . Dupa prelucrarea ei, ultima cifra va trebui inlaturata (N=N/10). Si totul trebuie repetat cat timp N mai are cifre (N!=0). De vreme ca nu stim cate cifre are N, nu putem folosi intructiunea FOR/PENTRU. Raman instructiunile repetitive cu un numar necunoscut de pasi : CAT TIMP EXECUTA/WHILE si EXECUTA CAT TIMP/ DO WHILE. Pentru CAT TIMP EXECUTA/WHILE am un contraargmuent. Algoritmul ar trebui sa fie

cat timp (N!=0) executa { //prel ultima cifra a lui N .......N%10; //stergem ultima cifra N=N/10; }
Daca utilizatorul doreste sa aplice algoritmul pentru valoarea zero, nu se va efectua nimic si secventa noastra nu se va executa.Evident, situatia se poate evita prin plasarea unui test inainte de CAT TIMP , care sa verifice daca N este nul. Nu ramane decat varianta cu EXECUTA CAT TIMP/DO WHILE.

executa{ //prel ultima cifra a lui N .......N%10; //stergem ultima cifra N=N/10; } cat timp (N!=0);

Cateva probleme clasice pentru acest algoritm: 1. 2. 3. 4. 5. 6. 7. 8. Sa se numere cate cifre are numarul N Sa se stabileasca cate cifre pare/impare are numarul N. Sa se stabileasca daca N contine o cifra data, CIF. Sa se numere de cate ori apare cifra CIF in numarul N. Sa se determine cifra maxima/minima din numarul N Sa se construiasca oglinditul numarului N. Pentru N=3648 se va afisa 8463. Sa se stabilesca daca N este palindrom (egal cu oglinditul sau). Pentru un numar N dat, sa se construiasca cel mai mare numar natural care se poate forma cu cifrele lui N.

cat timp (N!=0) executa { //prel ultima cifra a lui N .......N%10; //stergem ultima cifra

N=N/10; }

L7. Instructiunea EXECUTA CAT TIMP 14OCT


Exista trei instructiuni (structuri) repetitive folosite in toate limbajele: instructiunea repetitiva cu test initial CAT TIMP (WHILE) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu test final REPETA-PANA CAND/ EXECUTA CAT TIMP (DO WHILE sau REPEAT) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu un numar cunoscut de pasi PENTRU (FOR) (se foloseste cand numarul de repetitii este cunoscut)

Instructiunea EXECUTA CAT TIMP


Sintaxa: executa instructiune cat timp (expr_logica) Efect: 1. se executa instructiunea 2. se stabileste valoarea de adevar a expresiei logice 3. daca valoarea conditiei este ADEVARAT atunci se revine la pasul 1 4. daca valoarea conditiei este FALSA atunci se continua cu instructiunea de dupa EXECUTA CAT TIMP Observatii: instructiunea EXECUTA CAT TIMP este o instructiune repetitiva conditionata posterior (sau cu test final) intai executa instructiunea de repetat si apoi verifica necesitatea repetarii; instrutiunea se executa macar o data secventa de operatii este: instructiune, conditie, instructiune, , conditie, instructiune, cond itie Putewti folosi aceasta instructiune pentru algortimul de prelucrare a cifrelor unui numar natural N: executa {cif<- n%10; prelucrez cifra ; n<-n/10} cat timp (n!=0); Exemple: sa se afiseze cifrele numarului sa se numere cate cifre are N sa se stabileasca de cate ori apare o cifra anume sa se determine cifra maxima/minima din numar sa se creeze oglinditul numarului N (N=1234 => 4321) sa se stabileasca daca N estre palindrom (egal cu oglinditul sau). Ex: 12321, 11, 121,

L6. Instructiunea PENTRU EXECUTA 13AUG


Exista trei instructiuni (structuri) repetitive folosite in toate limbajele: instructiunea repetitiva cu test initial CAT TIMP (WHILE) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu test final REPETA-PANA CAND/EXECUTA CAT TIMP (DO WHILE sau REPEAT) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu un numar cunoscut de pasi PENTRU (FOR) (se foloseste cand numarul de repetitii este cunoscut - un numar fix de ori.)

Sintaxa: PENTRU contor<-exp_init,exp_fin EXECUTA instructiune Efect: pentru fiecare valoare a contorului intre expresia initiala si expresia finala se executa instructiunea;

Exemplu: pentru i <- 1,10 executa scrie Nu ma prinzi!; pentru fiecare valoarea a variabile i, de la 1 la 10, se afiseaza Nu ma prinzi! de 10 ori se afiseaza Nu ma prinzi! daca secventa ce trebuie repetata contine mai multe instructiuni, acestea se vor grupa cu acolade Observatii: practic, pentru fiecare valoare a lui i, intai se testeaza daca nu s-a depasit valoarea finala 10 si apoi se executa instructiunea; algoritmic, propozitia de mai sus este : o i<-1; cat timp (i<=10) {scrie Nu ma prinzi!; i<-i+1; }; practic , secventa de mai sus me explica faptul ca instructiunea pentru este o clona a instructiunii cat timp. instructiunea este ceruta daca descrierea algorimului spune de la valoarea X la valoarea Y, pentru primele X valori, de X ori,

Exemplul 1. Sa se afiseze numerele pare pana la o valaore N, naturala. intreg n,i; citeste n; pentru i<- 0,n executa daca (i%2==0) atunci scrie i. Observatii: algoritmul ia fiecare valoare intre 0 si n si o testeaza daca este para (restul impartirii lui i la 2 sa fie nul : i%2==0) se efectueaza n pasi din care jumatate sunt gresiti; trebuie o varianta mai buna

Exemplul 2. Aceeasi problema dar incercam sa mergem din doi in doi intreg n,i; citeste n; pentru i<-0,n,2 executa scrie i. intreg n,i; citeste n; pentru i<-0,n/2 executa scrie i*2.

o o

Observatie: in primul caz, 2-ul de dupa n (i<-0,n,2 ) stabileste cresterea lui i cu 2 si nu cu 1 asa cum este implicit in al doilea caz, ne folosim de faltul ca valorile cautate sunt pare, divizibile cu 2;

Exemplul 3 Sa se calculeze suma primelor N numere naturale. o evident, stim formula n*(n+1)/2 dar sa incercam un algoritm; o va trebui sa adunam, la o suma , toate valoarile de la 1 la n intreg n,i,suma; citeste n; suma<-0; pentru i<- 0 ,n executa suma<- suma +i; scrie suma. Exemplul 3. Se citeste un sir de N valori intregi. Sa se determine cea mai mare valoare citita (valoarea maxima dintr-un sir). intreg n,i,max,val; citeste n;

citeste max; pentru i<-2,n executa {citeste val; daca val>max atunci max<-val;}; scrie val.

INSTRUCTIUNEA FOR
Exista trei instructiuni (structuri) repetitive folosite in toate limbajele: instructiunea repetitiva cu test initial CAT TIMP (WHILE) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu test final REPETA-PANA CAND (DO WHILE sau REPEAT) (se foloseste cand numarul de repetitii este nedefinit) instructiunea repetitiva cu un numar cunoscut de pasi PENTRU (FOR) (se foloseste cand numarul de repetitii este cunoscut - un numar fix de ori.)

Sintaxa: FOR(initializare; test final; pasul urmator) instructiune; for (i=A; i<=B; i++) {secventa de repetat} for (i=1; i<=n; i++) {secventa de repetat} Efect: pentru fiecare valoare a contorului i intre expresia initiala si expresia finala se executa instructiunea; Exemplu: for (i=1; i<=n; i++) cout<< Nu ma prinzi!; pentru fiecare valoarea a variabilei i, de la 1 la N, se afiseaza Nu ma prinzi!; de N ori daca secventa ce trebuie repetata contine mai multe instructiuni, acestea se vor grupa cu acolade Observatii: instructiunea este ceruta daca descrierea algorimului spune de la valoarea X la valoarea Y, pentru primele X valori, de X ori,

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