Sunteți pe pagina 1din 37

Clasa 9-a , INFO

1.

Notiunea de algoritm

2.

Pseudocod. Date. Expresii

3.

Instructiuni de intrare/iesire. Atribuirea. AF: interschimbarea a 2 valori

4.

Instructiunea de decizie. AF: maximul a doua numere (psp;multimi)

5.

Instructiunea CAT TIMP ( xyz; capete; alo; cadouri;sume4;fazanr)


1.

AF:Prelucrarea sirurilor cu numar necunoscut de valori (care se incheie cu zero)

2.

AF:Calculul CMMDCsi CMMMC (ingerasi)

6.

Instructiunea PENTRU (case1; conturi; bancomat;gardul;rachete;prize;vraji;pin;barca;cabina)


1.

AF:Prelucrarea sirurilor cu numar cunoscut de valori

2.

AF:Divizibilitate. N este prim? (tort;vraji)

7.

Instructiunea EXECUTA CAT TIMP (triplu)


1.

AF:Prelucrarea cifrelor unui numar natural

8.

Care instructiune repetitiva este mai buna?

9.

AF: Conversia unui numar natural din baza 10 in baza B

10.

AF:Conversia unui numar din baza B in baza 10

11.

AF:Sirul lui Fibonacci

1.
L1. Notiunea de algoritm
Istoric. Definitie
Cuvantul algoritm provine de la numele unui matematician arab (Mohammed ibn-Musa al-Khowarizmi) a carui lucrari au fost
traduse in latina sub numele de Algoritmus.
Definitia actuala a cuvantului algoritm :
Ansamblu de simboluri folosite n matematic i n logic, permind gsirea n mod mecanic (prin calcul) a unor
rezultate.

Succesiune de operaii necesare n rezolvarea unei probleme oarecare

Din punctul de vederea al informaticii, algoritmul reprezinta rezolvarea etapizata, in pasi mici, elementari, a unei probleme.
Scopul folosirii algoritmului este aplicarea lui la o serie pe probleme care au aceeasi metoda de rezolvare; adica, pentru orice
dateale problemei, algortimul trebuie sa se incheie cu un raspuns.
Un exemplu in acest sens este acuatia de gradul I. Exista o infinitate de ecuatii de gradul I dar toate se subscriu aceleiasi ecuatii
generice A*X+B=0. Algoritmul trebuie sa rezolve aceasta ecuatie generica pentru a obtine rezultate corecte pentru intreaga clasa
se ecuatii de gradul I sau sa anunte eroarea in cazul in care simbolul A ar avea valoarea 0.

Caracteristici
Deducem de aici o serie de proprietati pe care un algoritm corect trebuie sa le indeplineasca:

sa aiba caracter de generalitate: sa rezolve o intreaga clasa de probleme de acelasi gen (pentru orice date de intrare)
sa aiba finitudine: sa ofere un raspuns la problema si sa se incheie in timp util
sa fie clar: calculul/etapele sa fie descriese intr-o maniera fara dubii
DATE DE INTRARE -> ALGORITM -> DATE DE IESIRE

Reprezentarea algoritmilor
S-au identificat cateva structuri folosite in descrierea unui algoritm:

secventa: pasii sa se execute unul dupa altul


testul: in cazul in care rezolvarea trebuie sa raspunda unei intrebari sa putem aplege traseul logic ce trebuie urmat
repetitia: sa putem repeta o anumita secventa daca algoritmul o cere

De asemeni, pentru exprimarea algoritmilor s-au incercat metode care sa poata fi intelese de toti. Iata cateve dintre ele:
scheme logice: metoda grafica care specifica traseul ce trebuie urmat
pseudocod: un set de reguli de scriere , in principiu in limba engleza; pt elevi s-a simplificat, folosindu-se aceleasi notatii
si limba romana (o varianta care se poate folosi in laborator gasiti la http://www.haskell.org/haskellwiki/Rodin/Download)

limbaj de programare: mult mai strict ca exprimare dar folosind aceleasi concepte.

Limbajul RODIN prezentare succinta


Obs: Nu exista declaratii de variabile

Programul principal

{ instr; }

Instructiuni de citire/afisare

citeste variabila;
scrie expresie;

text . text;

Atribuirea

fie variabila = expresie;

Operatori logici:

SAU, SI,

Instructiune de test

daca (COND) atunci instr altfel instr;

Instructiuni repetitive

cat timp (COND) {instr;};


executa {inst1; instr2;} atat cat (COND);
repeta {instr1; instr2;} pana cand (COND)
pentru (atribuire; test ;pasul urm) {instr;};

2.
L2. Pseudocod. Date. Expresii
Cuvantul pseudocod provine din pseudo, care inseamna fals, si cod care se refera la textul scris intr-un limbaj de programare.
Deci pseudocod inseamna un asa-zis limbaj de programare.
Pseudocodul foloseste aceeasi operatori si o exprimare la relaxata fata de un limbaj consacrat , care cere rigurozitate.
Pseudocodul, ca orice limbaj, foloseste date, variabile, operatii si instructiuni.
Pentru doritori, va prezint o varianta de pseudocod apropiata de cea din manual, limbajul Rodin a domnului profesor Dan Popa de
la Univeristatea Bacau. In acest fel puteti pigmenta orele de informatica din clasa a 9-a si cu ore de laborator. :)

Date
Datele cu care lucreaza un algoritm (scris in pseudocod) sunt:

valori intregi: 12, -5, 17


valori reale: 3.14, -1005.25, ; observati ca folosim punct zecimal si nu virgula ca in notatia de la matematica
valori logice: adevarat (true) si fals (false)
siruri de caractere: introdu valoarea:, rezultatul este:

Variabile
O variabila este un simbol care se caracterizeaza prin:

nume; se noteaza cu combinatii de litere sau cifre dar intotdeauna primul caracter este litera: a, Beta, nr1, nr2
tip de data: intreg, real, sir de caractere, logic
valoare: functie de tipul de data asociat, o variabila poate avea valori din cele de mai sus; valoarea memorata se poate
schimba, de unde si numele de variabila;

Practic, o variabila se comporta ca o cutie ce poate fi folosita doar pentru ceva anume: valorile intregi in cutii pentru valori intregi si
valori reale in cutii pentru valori reale; doar nu puneti zahar intr-o cutie de pantofi. :).
Din acest motiv, la inceputul algoritmului nostru in pseudocod trebuie sa specificam cu ce variabile lucram si ce tip au, ca in
exemplul de mai jos:
intreg m,n
real x,y.z
logic ok, exista, este

Expresii
Expresiile sunt foormate din operatori si operanzi. Formeaza expresie urmatoarele

o variabila
variabila operator variabila
expresie operator expresie
operator expresie (cazul operatorilor unari de genul - (5+3) )

Dintre operatorii folositi vom vorbi acum numai de cei intregi (care se folosesc numai pentru operanzi intregi):
semnul - se foloseste pentru scaderi sau ca operator unar
semnul + se foloseste pentru adunari
semnul * se foloseste pentru inmultiri
semnul / se foloseste pentru impartiri
semnul % se foloseste pentru a obtine restul impartirii primului operand la cel de al doilea
o
a % b = restul impartirii lui a la b
o
a % 2 = restul impartirii lui a la 2, care este 1 daca a este impar si 0 daca a este par
o
a % 10 = restul impartirii lui a la 10, care este intotdeauna ultima cifra a lui a, cifra unitatilor

prioritatea operatiilor este aceeasi ca in matematica; mai intai inmultirile si impartirile si apoi adunarile si scaderile

se pot folosi si paranteze pentru expresiile mai complicate, dar numai perechide paranteze rotunde

atentie la ordinea operatiilor si folosirea parantezelor rotunde (ex. ecuatia de gradul 2):
o
x1=-b+ radical(b*b-4*a*c)/2*a
o
x1=(-b+ radical(b*b-4*a*c))/2*a
o
x1=(-b+ radical(b*b-4*a*c))/(2*a)

care din variantele de mai sus este corecta?


o
prima imparte numai radicalul la 2, rezultatul este inmultit cu a si apoi se efectueza scaderea
o
al doilea exemplu pune parantezele pentru numarator dar imaprte numai la 2, rezultatul impartirii fiind inmultit cu
a
o
abia ultima varianta separa numitorul si numaratorul prin paranteze

3.
L3. Instruciuni intrare/ieire. Atribuirea
Instructiuni de intrare ieire
Asa cum am vazut in lectiile anterioare schema fluxului de date in rezolvarea unei probleme este urmatoarea:
Date de intrare -> Algoritm -> Date de iesire (Rezultate)
Deducem ca aven nevoie de o metoda de a prelua datele initiale (ale problemei reale) pentru a le putea prelucra in algoritm. De
asemenea, avem nevoie de o metoda de a transmite rezultatul calculului nostru.
Pentru preluarea datelor vom folosi instructiunea Citeste.
Sintaxa: Citeste variabila;
Exemplu: Citeste a;
Efect: Se citeste o valoarea care va fi memorata in variabila a
Observatii:
o
pentru intreg n; citeste n , nu putem introduce o valoare reala (3.14) deoarece variabila n este declarata ca
fiind intreaga

Pentru afisarea rezultatului vom folosi instructiunea Scrie:


Sintaxa: Scrie expresie
Exemplu: Scrie a
Efect:
o
instructiunea Scrie afiseaza valoarea expresiei
o
presupunand ca ceea ce se scrie este transmis care monitor, atunci prima instructiune scrie afiseaza sirul de
caractere Rezultatul problemei iar cea de a doua afiseaza valoarea memorata in variabila a la acel moment

Observatii
o
pentruafisarea unor texte folosim text acesta este mesajul

instructiunea scrie afiseaza valoarea expresiei; atunci o instructiune de tipul Scrie a+b va afisa valoarea
calculata a expresiei a+b; adica se aduna valoarea lui a cu valoarea lui b si se afiseaza rezultatul expresiei

Pana acum, cel mai complicat algoritm pe care il putem scrie este cel de adunare a doua valori intregi:
Intreg a, b;
Citeste a, b;
Scrie a+b.
Daca ar fi doar atat :P

Atribuirea
Pentru a schimba valoarea unei variabile pot folosi citirea. Daca totusi doresc ca variabila sa primeasca valoarea unei expresii
calculate pe parcursul algoritmului, atunci am nevoie de atribuire:

Sintaxa: variabila<- expresie;


Efect: In cutia variabilei se memoreaza valoarea expresiei;
Exemplu:
intreg a; a<- 10;
real b; fie b<- 3.14;
sir c; fie c<- totul e ok;
Observatie:

o
o
o
o
o

noua valoare se memoreaza peste vechea valoare care se va pierde; adica, se inloceste vechea valoare cu cea noua
in fiecare din exemple in variabila se memoreaza o valoare de acelasi tip cu variabila; nu putem memora intr-o variabila o valoare de alt tip:

o
o

secventa intreg a; a<-3.14; scrie a; nu este corecta; variabila a este de tip intreg si nu poate memora o valoare reala.
secventa real a; a<- +10; este corecta deoarece valoarea intreaga 10 este si valoare reala, conform incluziunii matematice.
greselile frecvente sunt cele in care valori obtinute in urma unor impartiri sau radicali (valori reale) sunt atribuite unor variabile intregi
operatiile cele mai de intalnite la atribuire sunt incrementarea (marirea cu 1 a valorii variabilei) si decrementarea (micsorarea cu 1 a valorii variabilei)
incrementarea: a<- a+1;

asa cum stim , intai se calculeaza valaorea expresiei (cresterea cu 1 a lui a) si apoi se memoreaza in variabila, peste vechea valoare
decrementarea: a<- a-1;

se calculeaza valoarea expresiei (scadereacu 1 a lui a) si apoi se memoreaza in variabila, peste vechea valoare

Exemplul 1: calculul vitezei, atunci cand stim valoarea distantei parcurse si timpul necesar;
real viteza;
intreg timp, distanta;
citeste timp, distanta;
viteza <- distanta/timp;
scrie viteza.

Exemplul 2 (interschimbarea a doua variabile folosind auxiliar). Fie doua variabile intregi. Sa se interschimbe valorile
variabilelor. Daca variabila a are valoarea 5 si variabila b are valoarea 7, dupa executarea algorimului, variabila a sa aiba valoare 7
si variabila b sa aiba valoare 5.
intreg a, b, aux;
citesc a, b;
aux<-a;
a<-b;
b<-aux;
scrie a, b.
observatie: problema este similara cu urmatoarea problema. Aveti un pahar de bere (rolul variabilei a) si o halba de suc
(rolul variabilei b). Pentru a schimba bauturile aveti nevoie de o cana goala (rolul variabilei aux);
o
turnam in cana goala continutul paharului
o
turnam in pahar continutul halbei
o
turnam in halba continutul canii
o
acum toate sunt in ordine; berea in halba si sucul in pahar si gana este goala; NU BEM DECAT SUCUL!

Exemplul 2 (interschimbarea valorii a doua variabile fara auxiliar). Avem aceeasi problema dar trebuie rezolvata fara o
variabila in plus.
intreg a, b;
citeste a,b;
a <- a+b; b<- a-b; a<- a-b;
scrie a,b.

4.
L4. Instruciunea de decizie
Fara instructiunea de decizie sau de test (in nici un caz detest) algorimul ar fi linear. Aceasta instructiune ne ajuta in cazul in care
avem o intrebare privind natura datelor folosite, a valorii lor la un moment dat.
Practic, trebuie sa punem intrebari la care algoritmul sa raspunda cu adevarat/fals; ce operatori folosim pentru a obtine raspunsuri
adevarat/fals?

Expresii cu valoare logica (adevarat/fals)


Operatori de relatie:

o
o
o
o
o
o

> inseamna mai mare


a>b are valoarea adevarat numai daca valoarea variabilei a este mai mare decat valoarea variabilei b
< inseamna mai mic
a<b are valoarea adevarat numai daca valoarea variabilei a este mai mica decat valoarea variabilei b
>= inseamna mai mare egal
a>b are valoarea adevarat numai daca valoarea variabilei a este mai mare sau egala cu valoarea variabilei b
<= inseamna mai mic sau egal
a>b are valoarea adevarat numai daca valoarea variabilei a este mai mica sau egala cu valoarea variabilei b
= inseamna egal
a=b are valoarea adevarat numai daca variabila a are aceeasi valoare cu variabila b
!= inseamna diferit
a!=b are valoarea adevarat numai daca variabila a NU are aceeasi valoare cu variabila b

Operatori logici
Operatorii logici (cu care lucreaza si logica matematica) sunt SI, SAU si NEGARE:

Operatorul SI este un operator binar, cu doi operanzi cu valoare logica. Rezultatul operatorului SI este adevarat numai
daca ambii operanzi au valoarea ADEVARAT.
o
Mie imi place fata bruneta si cu ochi albastri!
o
daca fata nu este bruneta sau nu are ochi albastri nici nu ma uit la ea (:P), ceea ce inseamna fals; daca macar
una dintre conditii este falsa atunci intreaga expresie este falsa
Operatorul SAU este un operator binar cu doi operanzi cu valoare logica. Rezultatul operatiei SAU este adevarat daca
macar unul din operanzi are valoarea ADEVARAT.
o
Mie imi place fata bruneta SAU cu ochi albastri!
o
Fata nu trebuie sa aiba ambele calitati. Daca este bruneta imi place (ADEVARAT). Daca este cu ochi albastri imi
place (ADEVARAT).
o
Daca macar una din conditii este adevarata atunci intreaga expresie este adevarata
Operatorul de negatie (vom folosi semnul ! ) schimba valoarea de adevar a expresiei: !ADEVARAT==FALS si !FALS
==ADEVARAT

Exemple:
X apartine [-5, -2]
o
(x>=-5) SI (X<=-2)

x apartine (0, 10)


o
(x>0) SI (x<10)

x nu apartine (-7,9]
o
(x<=-7) SAU (x>9)
o
!(x>-7) SAU !(x<=9)
o
!((X>-7) SI (x<=9))

Observatii
prioritatea operatorilor logici: negare, SI, SAU
in cazul expresiilor logice se pot aplica regulile lui De Morgan:

o
o

!( exp1 si exp2) = !exp1 sau !exp2


!(exp1 sau exp2) = !exp1 si !exp2

Instructiunea de decizie (de test; sau detest :P)


Sintaxa:
daca (exp_logica) atunci instructiune1
[altfel instructiune2;]
Efect: Se evalueaza expresia logica; daca valoarea logia ca expresiei este ADEVARAT se executa intructiunea 1; Daca exista
sectiunea ALTFEL si valoarea logica a expresiei este FALS se executa intructiunea 2; in ambele cazuri, dupa executarea
intructiunii corespunzatoare si executa ce instructiune urmeaza dupa testul nostru.
Observatie. Un algoritm trebuie sa fie clar si sa poata fi inteles intr-un singur fel. Din acest punct de vedere, exista doua moduri de
a scrie un algoritm:
cate o instructiune pe linie si cu marcatori la sfarsitul instructiunilor de test si repetitive (cum cere manualul)
mai multe instructiuni pe line, separate printr-un marcator; pentru cazul cand un grup de instructiuni trebuie executate
impreuna pe unul din cazurile intrtuctiunii de decizie (de exemplu ), acestea pot fi incadrate cu acolade (in limbajul C++) sau cu
cuvinte rezervate (begin end);

Pentru ca pdeudocodul nu este un limbaj in sine ci doar o conventie de notatii, sugerez sa folosim deja notatiile din C++;

cand o secventa de instructiuni trebuie executate una dupa alta, datorita logicii algoritmului, acea secventa o vom incadra
in acolade (de exemplu: {instructiune1; instructiune2; instructiune3; }); vom reveni cu amanunte.

Exemple:
Sa se afiseze maximul a doua valori citite.

intreg a,b;
citeste a,b;
daca (a>b) atunci scrie a
altfel scrie b.
Sa se afiseze modulul (matematic) al unui numar intreg.

intreg a;

citeste a;
daca (a>0) atunci scrie a
altfel scrie -a.
Sa memoram valoarea maxima intr-o variabila si sa o afisam.

intreg a,b,max;
citeste a,b;
daca (a>b) atunci max<-a
altfel max<-b;
Scrie max.
Sa se citeasca o valoare intreaga si sa se stabileasca daca s-a citit o valoare para sau nu.

intreg a;
citeste a;
daca (a%2 ==0) atunci scrie Valoarea citita este para!

altfel scrie Valoarea citita este impara!.


Fie a si b coeficientii unei ecuatii de grad 1. Sa se afiseze solutia ecuatiei a*x + b =0;
evident x=-b/a daca a!=0;

intreg a,b;
real x;
citeste a,b;
daca (a!=0) atunci { x<- -b/a; scrie Solutia ecuatiei este ; Scrie x;}
altfel scrie Nu se poate calcula solutia ecuatiei.
Secventa { x=-b/a; scrie Solutia ecuatiei este ; Scrie x;} trebuie gandita ca un intreg deoarece este valabila numai pentru cazul in
care a este nenul; de aceea am incadrat-o intre acolade.
Fie a, b si c coeficientii unei ecuatii de grad 2 (a*x^2+b*x+c=0). Sa se calculeze valorile radacinii, daca exista.
o
conditia pentru a fi ecuatie de grad 2: coeficientul a trebuie sa fie nenul (a!=0)
o
trebuie calculata valoarea DELTA=b*b-4*a*c
o
pentru a avea solutii, valoarea DELTA trebuie sa fie pozitiva, cel putin nula;
o
vom folosi radical (expr) pentru a calcula valoarea radicalului unei expresii reale/intregi

intreg a,b,c,delta;
real x1,x2;

citeste a,b,c;
daca (a==0) atunci scrie Coeficientii nu formeaza ecuatie de gradul 2;
altfel {delta=b*b-4*a*c;
daca (delta<0) atunci scrie Nu se pot calcula radacini reale
altfel {x1<- (-b+radical(delta))/(2*a); x2<- -b-radical(delta))/(2*a);
scrie Solutiile sunt :, x1, , x2; }
}
Observatii:
x1 si x2 sunt declarati reali pentru ca se obtin in urma radicalului si a unei impartiri
urmariti daca algoritmul scrie concide cu termenii problemei
pentru cazul coeficientului a nenul trebuie efectuate doua operatii (calculul lui delta si testul lui delta), motiv pentru care
acestea au fost incadrate intre acolade

la calculul solutiilor au fost puse paranteze pentru separarea numitorului si a numaratorului

de asemenea, aici au trebuit puse acolade pentru calculul celor doua solutii si a afisarii solutiilor

Fie o functie matematica data pe intervale. Sa se calculeze valoarea functiei intr-un punct x oarecare daca expresia
functiei este:
o
x^2+2*x+1 daca x<0
o
3*x+5 daca x apartine [0,5)
o
-x+2 daca x>=5
o
este clar ca valoarea functie difera pe cele trei intervale; va trebui sa verificam, pe rand, carui interval apartine
valoarea citita pentru x;

real x,f;
citeste x;
daca (x<0) atunci f<- x*x+2*x+1
altfel daca (x>=5) atunci f<- -x+2
altfel f<- 3*x+5;
scrie f.

5.
L5. Instruciunea repetitiv CT TIMP
Chiar si cu atribuirea si intructiunea de decizie, si tot nu este de ajuns. Exista probleme ce necesita repetarea unor operatii si cu
ceea ce stim, nu putem face fata.
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 CAT TIMP


Sintaxa: cat timp (expresie_logica) executa instructiunea;
Efect:
1.
2.
3.

se stabileste valoarea de adevar a expresiei logice


daca valoarea expresiei logice este ADEVARAT atunci se executa instructiunea si se reia de la pasul 1
daca valoarea expresiei logice este FALS atunci se continua cu instructiunea de dupa CAT TIMP

Observatii:
CAT TIMP este repetitiva conditionata anterior deoarece intai se evaluaeza conditia si apoi se executa instructiunea
Practic, succesiunea de etape este exp logica, instructiune,exp logica, instructiune,exp logica,instructiune,exp
logica;succesiunea se incheie cu exp logica in momentul in care valoarea expresiei este FALS.

daca pe cazul ADEVARAT trebuie sa scriem mai multe instructiuni, acestea vor fi grupate cu acolade

Exemplul 1
Fie a si b doua valori naturale. Se se simuleze inmultirea a*b prin adunari repetate.
o
P=a*b=a+a+.+a de b ori
o
Expresia de mai sus spune ca a trebuie adunat la P de b ori; adica, la fiecare adunare la P a lui a putem sa
scadem un 1 din b (decrementam), pentru a pastra numarul de adunari ce mai trebuie efectuat; candb va fi zero , se va
adunat a de b ori

intreg a,b,p;
citeste a,b;
p<-0;
cat timp (b>0) executa {p<- p+a; b<- b-1;};
scrie p.
Observatii:
pentru fiecare adunare a lui a la p, scadem un 1 din b
aceste operatii trebuie executate pentru fiecare caz in care b este pozitiv; de aceea au fost grupate cu acolade
este algoritmul corect? Sa verificam cazurile cu zero:
o
daca a este zero, atunci la P se aduna zero de b ori; practic P ramane la valoarea zero. CORECT!
o
daca b este zero, conditia din CAT TIMP este falsa si atunci nu se executa instructiunile; in consecinta se
afiseaza direct valoarea lui P,adica zero; CORECT!

Exemplul 2
Fie a si b doua valori naturale. Sa se simuleze impartirea lui a la b prin scaderi repetate si sa se afiseze catul si restul.
o
vom scadea din a valoarea lui b de mai multe ori, numarand intr-o variabila contor de cate ori am facut scaderea
(practic variabila contor va fi catul impartirii)
o
operatia se va repeta cat timp din a se mai poate scadea un b, adica cat timp a mai mare decat b
o
Ce reprezinta valoarea ramasa in a? O valoare mai mica decat b? Evident, restul impartirii.

intreg a, b, contor;
contor<- 0;
daca (b=0) atunci scrie nu se realizeaza impartiri la zero!;
altfel {cat timp (a>=b) executa {a<- a-b; contor<-contor+1;};
scrie catul este , contor;
scrie restul este , a;
}.
Observatii:
am pus intre acolade secventa in care numaram de cate ori am scazut pe b din a; erau doua instructiuni;
este corect algoritmul? Daca incercati cazurile normale, va merge. Sa verificam cazurile speciale:
o
daca a este mai mic decat b atunci cat timp nu va functiona si se va afisa direct contor (zero) si a(restul);
CORECT!
o
daca a este zero, atunci nu se executa cat timp si se afiseaza contor si a (0 si 0 ) CORECT!
o
daca b este zero, se afiseaza mesajul de eroare si algoritmul se incheie CORECT!

Exemplul 3.
Sa se calculeze cel mai mare divizor comun a doua valori a si b naturale.
o
asa cum spune definitia, cel mai mare divizor comun trebuie sa fie o valoare, care sa divida atat pe a cat si pe b;
aceasta valoare poate fi in cel mai bun caz a sau b

intreg a,b;
citeste a,b;
cmmdc<- a;
cat timp (a%cmmdc +b%cmmdc !=0) executa cmmdc<- cmmdc-1;
scrie cmmdc.
Observatii:
expresia a%cmmdc +b%cmmdc !=0 este nula doar daca atat a%cmmdc cat si b%cmmdc sunt nule, adica cmmdc divide
simultan a si b; atat timp cat aceasta conditie nu se realizeaza scadem cmmdc-ul

ultima valoare panaa la care se poate scadea este 1, divizorul tuturor numerelor; in acest caz a si b se numesc numere
prime intre ele.

Exemplul 4
Ghiceste-mi numarul! Eu imi aleg un numar intre 1 si 100. In cati pasi il poti ghici? La fiecare incercare raspund cu
SUCCES, MIC sau MARE.
o
prima varianta este sa intrebam aleator; cam multi pasi!
o
sa parcugem valorile de la 1 la 100; cam multi pasi!

sa gandim! vom testa intodeauna mijlocul intervalului; in acest fel, la fiecare intrebare, elimin jumatate din cazuri.

intreg x,m1,m2, mij, pasi;


citesc x; m1 <- 1; m2<- 100;
mij<- 50; pasi<- 0;
cat timp (mij!=x) executa
{daca (x<mij) atunci m2<- mij;
altfel m1<- mij;
mij<-(m1+m2)/2;
pasi<- pasi +1;};
scrie pasi.
Observatie:
dupa fiecare test fara succes intervalul in care cautam se ajusteaza la stanga (daca mij este mai mic decatx) sau la
dreapta (daca mij este mai mare decat x)

Exemplul 5.
Fie N un numar natural. Sa se calculeze suma cifrelor lui N.
o
vom initializa o variabila suma cu zero
o
trebuie ca delimitam pe rand cifrele care formeaza numarul N; putem determina rapid ultima cifra: n%10; daca o
stergem (n<- n/10) putem deternima penultima cifra; s.a.m.d.
o
cand ne oprim? cand N nu mai are cifre; deci , cand N este zero.

intreg n, suma;
citeste n;
suma <-0;
cat timp (n!=0) executa {suma<-suma+n%10; n<-n/10;};
scrie suma.
Observatie:
instructiunea suma<-suma+n%10 creste suma cifrelor deja obtinute cu valoarea ultimei cifre a lui n.
pentru cazul in care n este nul, cat timp nu se mai executa si se afiseza suma cu valoarea 0; Suma cifrelor lui 0 este 0.
CORECT!

5.1
L9. Algoritmi fundamentali. iruri de numere
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 ir cu numr 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 ir cu un numr necunoscut de valori (care se ncheie 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 saunu.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.

Sa se calculeze suma/produsul valorilor din sir

2.

Sa se determine valoarea minima/maxima dintre valorile citite.

3.

O valoare data Y se gaseste in sir?

4.

De cate ori apare o valoare data Y?

5.

Presupunand ca sirul reprezinta coeficientii uni polinom ( dati incepand cu gradul cel mai mic), calculati valoarea polinomului intr-un
punct Y.

5.2
L11. Cmmdc. Cmmmc
C.m.m.d.c. este acronimul (prima liter de la fiecare cuvnt) de la cel mai mare divizor comun i se aplic pentru dou 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.

6.
L6. Instructiunea PENTRU EXECUTA
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
o
intreg n,i; citeste n; pentru i<-0,n,2 executa scrie i.
o
intreg n,i; citeste n; pentru i<-0,n/2 executa scrie i*2.

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.

6.1
L9. Algoritmi fundamentali. iruri de numere
Pentru a prelucra un ir de numere trebuie s tim fie numrul de valori n discuie (ir cu numr cunoscut de valori), fie s avem o
valoare care s marcheze sfritul irului (de obicei zero).

Prelucrarea unui ir cu numr 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 ir cu un numr necunoscut de valori (care se ncheie 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 saunu.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.

Sa se calculeze suma/produsul valorilor din sir

2.

Sa se determine valoarea minima/maxima dintre valorile citite.

3.

O valoare data Y se gaseste in sir?

4.

De cate ori apare o valoare data Y?

5.

Presupunand ca sirul reprezinta coeficientii uni polinom ( dati incepand cu gradul cel mai mic), calculati valoarea polinomului intr-un
punct Y.

6.2
L10. Algoritmi fundamentali. Divizibilitate. N este prim?
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 numr prim?


Problema. Fie N un numr natural. Este N numr 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.

7.
L7. Instruciunea EXECUT CT TIMP
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 EXECUT CT TIMP


Sintaxa: executa instructiune cat timp (expr_logica)
Efect:
1.
2.
3.
4.

se executa instructiunea
se stabileste valoarea de adevar a expresiei logice
daca valoarea conditiei este ADEVARAT atunci se revine la pasul 1
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, conditie

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,

7.1
L8. Algoritmi fundamentali. Prelucrarea cifrelor unui numr natural
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;
}

8.
L7.2. Care instruciune repetitiv este mai bun?
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};

9.
L14. Conversia unui numr din baza 10 n 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.

10.
L13. Conversia unui numr din baza B n baza 10
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;

11.
L12. irul lui Fibonacci
irul lui Fibonacci este 1, 1, 2, 3, 5, 8, 13, 21, 34, . i are legtur cu celebrul numr de aur.
Se observ c irul ncepe cu valorile 1 i 1 , dup care, fiecare nou valoare se obine prin adunarea ultimelor dou 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 ir.


Dac N=1 sau N=2, rspunsul este simplu, 1. n restul cazurilor trebuie ca avnd mereu ultimile valori A si B, s calculm noua
valoare C=A+B (mereu trebuie memorat noua pereche format ultimile doua valori determinate)
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;}

Clasa a 10-a, INFO

Limbajul C/C++
1. Alfabet, identificatori, constante , variabile
2. Tipuri
3. Operatori. Expresii
4. Structura unui program C/C++
5. Citirea. Afisarea
6. Atribuirea
7. Instructiunea IF
8. Instructiunea DO WHILE
9. Instructiunea WHILE
10. Instructiunea FOR
11. Algoritmi fundamentali
1.

Conversia unui numar din baza 10 in baza B

2.

Conversia unui numar din baza B in baza 10

3.

Sirul lui Fibonacci

4.

Cmmdc. Cmmmc

5.

Divizibilitate. N este prim?

6.

Prelucrarea sirurilor de numere

7.

Prelucrarea cifrelor unui numar natural

12. Tablouri.

1.

L3. Alfabet, identificatori, constante , variabile


29NOV
Alfabetul
Alfabetul folosit in limbajul C/C++este format din:

litere mici: a-z


litere mari: A-Z
cifre: 0-9
semne speciale: {}[]:;<>=+*-|,.%#!()&

Identificatori
Cu caracterele din alfabetul de mai sus se pot construi cuvinte. In programare aceste cuvinte se
numescidentificatori. Identificatorii sunt de doua tipuri:

identificatori proprii limbajului (cuvinte rezervate, din care sunt formate instructiunile): for, while, if, do,

identificatori ai programatorului: trebuie sa fie formati din litere, cifre si semnul _ ; regula este ca primul
caracter sa fie obligatoriu litera.
Identificatorii programatorului pot avea rolul:

nume de constante (simboluri a caror valoare nu se modifica pe parcursul executiei programului)


nume de variabile (simboluri a caror valoare se modifica pe parcursul executiei programului)
nume de tipuri create de utilizator (de ex: vector, matrice, punct la structuri)

Variabilele
O variabila este un identificator, purtator a unei singure valori. O variabila se caracterizeaza prin:

nume

tip de data (ceea ce determina spatiul de memorie alocat variabilei si in consecinta, domeniul de
valori care se pot memora in variabila respectiva)

locatie de memorie
Exista si aici cateva reguli:

2.

in principiu, la inceputul programului trebuie sa declarati ce variabile folositi si tipul fiecareia din ele
nu puteti folosi o variabila nedeclarata sau care inca nu a primit valoare (neinitializata);
o exceptie de la regula o reprezinta cazul valorilor intregi care se initializeaza automat cu zero (ordonat ar fi
sa cititi sau sa initializati voi fiecare variabila)
limbajul C/C++ face distinctie intre litere mari si mici
o
identificatorul FOR va genera eroare, pentru ca limbajul cunoaste doar for;
o
variabilele NR, nR, nr, Nr sunt diferite din punctul de vedere al C/C++

L4. Tipuri
Tipurile intregi
Tipurile intregi din C/C++ sunt: enum, short int, int, unsigned int, long, unsigned long.
Pentru fiecare variabila se aloca (rezerva) un spatiu de memorie conform cu tipul ei. Acest lucru influenteaza domeniul de valori
care se poate aloca variabilei:

o
o
o
o

o
o
o
o

enum, short int, int:


spatiu: 16 biti
domeniu: -32768..32767
unsigned int
spatiu: 16 biti
domeniu: 0..65535
long
spatiu: 32 biti
domeniu:-2147483648 .. 2147483647
unsigned long
spatiu: 32 biti
domeniu:0 .. 4294967295

Observatii:
valorile UNSIGNED (eng: fara semn) sunt valori naturale, cu valori pozitive
in sprijinul ideii de mai sus, ca tipul determina domeniul de valori, venim cu urmatoarea demonstratie:
o
presupunem ca avem o variabila A de tip int (pe 16 biti); aceasta inseamna ca valoarea maxima ce se poate
memora este un sir de 15 pozitii binare cu 1 (primul bit memoreaza semnul); daca convertim aceasta valoare din baza 2 in
baza 10 (puteti folosi aplicatia CALCULATOR din Windows) obtinem exact 32767
o
analog, pentru o variabila unsigned int (16 biti) putem memora 16 pozitii binare cu 1 (din cauza unsigned, nu mai
avem semn adica valori pozitive); sirul de 16 pozitii binare reprezinta valoarea 65535 din baza 10.

Tipurile reale

float(32 biti): 3.4 * (10**-38) .. 3.4 * (10**+38)


double(64 biti): 1.7 * (10**-308) .. 1.7 * (10**+308)
long double(80 biti): 3.4 * (10**-4932) .. 1.1 * (10**+4932)

Tipul caracter

char -127 .. 127 (pentru fiecare caracter este asociata, in mod unic, o valoare de la 0 la 127; aceasta asociere se
numeste CODUL ASCII)

3.

L5. Operatori. Expresii


Valorile variabilelor interactioneaza intre ele prin operatii. Simbolurile prin care reprezentam aceste operatii se numesc operatori.
Combinatiile care apar in urma folosirii operatorilor si variabilelor/constantelor se numescexpresii.
O expresie poate fi:
o constanta/variabila
o combinatie de tipul operator expresie (cazul operatorilor unari: a)
o combinatie de tipul expresie operator expresie (cazul operatorilor binari: a+b )

Operatorii folositi in C/C++ sunt:

operatori aritmetici: +,-,*, /, %

o
o

A/B reprezinta catul impartirii lui A la B


A%B reprezinta restul impartirii lui A la B
A%10 reprezinta ultima cifra a lui A
A%2 va avea valoarea zero daca A este par si 1 daca A este impar

Prioritatea operatorilor

4.

L6. Structura unui program C/C++


In general, un program este un sir de instructiuni. In C/C++ programul este o functie numita main.
Efectul instructiunillor din C/C++ este stabilit intr-un fisier numit stdio.h (h vine de la header). Acest fisier este incarcat implicit
pentru a asigura buna functionare a programului. Daca dorim sa folosim instructiuni mai complexe (gen cin, cout) trebuie sa
specificam si headerul care explica functionarea acestor instructiuni (iostream.h).
De asemenea, trebuie sa stabilim ce variabile folosim, pentru a le putea aloca spatiu si a le da valori. Spre deosebire de alte
limbaje, in C/C++ declararea variabilelor folosite poate fi facuta si pe parcursul executiei programului.
Structura unui program C/C++ este urmatoarea

//acesta este un comentariu; el nu influenteaza programul


//declararea headerelor
#include <iostream.h>
//declararea variabilelelor
....
//programul principal
int main()
{
// instructiunile programului
..........
return 1;} //aici se incheie programul
In exemplul urmator (citirea a doua valori si afisarea sumei lor) trebuie sa observati:
1.
orice program are trei parti:
2.
citirea datelor initiale si initializarea variabilelor necesare

3.

prelucrarea datel;or (programul propriuzis)

4.

afisarea rezultatelor

Puteti observa de asemenea:

cum se declara o variabila

cum se foloseste o constanta text (sir de caractere)

cum se citeste o data

cum se afiseaza un sir de caractere, constante, variabile si expresii

cum putem schimba valoarea unei variabile


# include <iostream.h>

int a,b,c;
int main()
{//citirea datelor initiale; initializarea altor variabile;
cin>>a>>b;
//prelucrarea datelor
c=a+b;
//afisarea datelor
cout <<"afisarea rezulattului"<<endl;
cout<<<<a<<'+'<<b<<'='<<a+b;
cout<<"Suma calculata

este "<<c;

return 1;}
Observatie
instructiunea return permite intreruperea brusca a executiei unui program; puteti folosi aceasta instructiune daca , din
diverse motive doriti intreruperea brusca a executiei unui program.

5.

L7. Citirea. Afisarea


Programele in limbajul C folosesc instructiunile printf (pentru afisarea datelor) si scanf (pentru citirea datelor) ca operatii de
intrare/iesire.
Pentru usurinta operatiilor de citire/afisare vom folosi instructiuni consacrate in C++: cin si cout.

Instructiunea CIN
Sintaxa: cin>>variabila1>>variabila2;
Efect: se preiau de la tastatura (Console INput) valori pentru fiecare variabila din sir;
Cerinte : folosirea instructiunii necesita #include <iostream.h>
Exemplu:
int A,B; cin>>A>>B;
Pe rand, se introduc valori de la tastatura pentru variabilele intregi A si B.

Instructiunea COUT
Sintaxa: cout<<expresie1<<expresie2;
Efect: se afiseaza, pe rand, valorile expresiilor;
Cerinte: necesita, de asemenea, folosirea #include <iostream.h>
Exemple:
cout<<Rezultatul este<<endl<< A<<+'<<B<<='<<A+B;
s-au afisat :
o
constanta sir de caractere (text) Rezultatul este
o
constantele caracter + si =
o
valorile variabilelor A si B
o
valoarea expresiei A+B

6.

L8. Atribuirea
Variabilele pot primi valori prin citire sau atribuire.

Atribuirea
Sintaxa: variabila=expresie;
Efect:

se calculeaza valoarea expresiei


aceasta valoare se scrie in variabila, peste vechea valoare, care se pierde

Exemple:
A=0;
B=5;
A=B+6;
A=B+A; (in A se va memora suma dintre A si B)
un caz deosebit este incrementarea (cresterea cu 1 a valorii unei variabile)
o
a=a+1;
o
aceasta operatie se mai scrie a++; (++ este operator unar)

operatia analoga, de scadere cu 1 a valorii unei variabile, se numeste decrementare:


o
a=a-1;
o
sau a;

citind diverse programe realizate in C/C++ puteti intalni si exprimari de genul:


o
a=a+ b; cu semnificatia b; a=a+b; (analog ++b)
o
a+=b; cu semnificatia a=a+b;

cum va place!

Probleme
1.
Teodor is consuma jumatate din salariul sau pe facturi. Cititi salariul lui Teodor si afisati cu cat ramane Teodor.
2.
Cititi de la tastatura distanta si timpul necesar unui tren pentru a parcurge respectiva distanta. Calculati viteza medie de
deplasare.
3.
Ana si Bogdan sunt colegi de banca. In pauza s-au gandit sa-si schimbe scaunele intre ei astfel incat , in orice moment,
fiecare sa stea pe un scaun. Copiii astia chiar n-au treaba!!!
Observatii:
la problema 1 pot apare urmatoarele dificultati:
o
daca salariul are valoare impara, rezultatul nu este real => float rez=(float) salar/2;
o
salariul este declarat int salar; si introduceti un salariu mai mare de 32767 rezultatele sunt imposibile; de ce? =>
variabilele de tip int nu pot depasi 32767; de aceea, valorile mai mari sunt trunchiate

la problema 2, pe langa valori de bun simt, puteti incerca si impartirea la zero :)

problema 3 face apel la o tehnica de lucru numita interschimbarea a doua valori;


o
una dintre variantele de rezolvare face apel la inca un scaun (variabila): int aux=a; a=b;b=aux;
o
exista si o varianta fara variabila auxiliara (pentru cazul in care vorbim de valori :) ): a=a+b; b=a-b;a=a-b;

Sa privim inainte:
din exemplele de mai sus este limpede ca variabilele/datele de intrare trebuiesc verificate inainte de a fi prelucrate
de aceea, vom studia in continuare instructiunea IF

7.

L9. Instructiunea IF
Instructiunea IF
Sintaxa: if (exp_logica) instrDA; else instrNU;
Efect:

se evalueaza valoarea expresie logice


daca valoarea calculata este adevarata (nenula) se executa instructiunea instrDA si apoi instructiunea de dupa IF
daca valoarea calculata a expresiei este nula se executa instructiunea instrNU (daca exista ramura ELSE) si apoi
instructiunea de dupa IF

Exemplu:
if (a%2==0) cout>>valoarea este para; else cout<< valoarea este impara;
se verifica daca restul impartirii la 2 a variabilei A este zero
daca DA se executa cout>>valoarea este para;
daca NU se executa cout>>valoarea este impara;

Observatii:
in C/C++ instructiunile, pe langa efectul lor, returneaza o valoare adevarat (1 unu) daca se executa corect si fals (0
zero) daca executia a fost eronata;

secventa if (a=b) instr1; else instr2; va executa intotdeauna numai instr1 pentru ca atribuirea a=b se executa corect

a nu se confunda a=b (lui a i se atribuie valoarea lui b) cu a==b (care verifica daca cele doua valori sunt egale)

daca in loc pentru o valoare a conditiei testate algortimul impune executarea a mai mult de o instructiune, acestea se vor
incadra intre acolade: if (conditie) { instructiuni pe ramura DA} else {instructiuni pe ramura NU};

Probleme:
1.
Fie N un numar natural. Sa se afiseze textul PAR sau IMPAR, functie de valoarea lui N.
2.
Fie N un numar natural. Sa se afiseze textul POZITIV, NEGATIV sau ZERO dupa caz.
3.
Fie A si B capetele unui interval. Sa se stabileasca daca o valoare X apartine intervalului [A,B].
4.
Fie A si B doua valori intregi. Sa se afiseze A si B in ordine crescatoare.
5.
Fie A si B doua valori intregi. Sa se calculeze X, solutia ecuatiei A*X+B=0.
Observatii:
1.
Se verifica valoarea expresiei N%2==0
2.
Se compara N cu 0 si se afiseaza dupa caz.
3.
Daca A este mai mare decat B, valorile trebuie interschimbate.
4.
5.
Trebuie verificat daca A nu este zero, caz in care se afiseaza un mesaj si se iese fortat, cu RETURN.

8.

L10. Instructiunea DO WHILE


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.)

Instructiunea DO WHILE
Sintaxa: do { instructiuni} while (conditie) ;
Efect:
1.
2.
3.
4.

se executa secventa de instructiuni


se evalueaza conditia
daca valoarea conditiei este adevarata se revine la pasul 1
daca valoarea conditiei este falsa se continua cu instructiunea de dupa punct si virgula

Observatii:
do-while se mai numeste instructiune cu test final sau conditionata posterior
observati ca intai se executa secventa de instructiuni (macar o data) si apoi se testeaza
succesiunea de operatii este instructiune, test, instructiune, test, .. test, instructiune, test.

Exemplu:
O problema la care putem folosi DO-WHILE este prelucrarea cifrelor unui numar natural/intreg. Cifrele vor fi prelucrate pe rand, de
la sfarsitul numarului catre inceput, de fiecare data taind ultima cifra (deja prelucrata). Algoritmul se reia pana cand nu mai sunt
cifre in numar, adica valoarea N ajunge la valoarea zero.
Sesizati ca orice numar are o ultima cifra, motiv pentru care intai prelucrez si tai , si apoi verific daca mai sunt cifre de prelucrat.

Scheletul algoritmului ar fi:

cin>>n;
do { //prelucrarea ultimei cifre
..............;
// tai ultima cifra
n=n/10;
} while (n!=0);
Observatii: puteti determina intai ultima cifra (int uc=n%10; ) si apoi sa prelucrati variabila uc
Probleme. fie N un numar natural.
1.
Cate cifre are N?
2.
Care este suma cifrelor lui N?
3.
Care este cea mai mare cifra din numar? (valoarea maxima). Analog minima.
4.
Sa se determine prima cifra a numarului N.
5.
De cate ori apare o cifra data C, in numarul N?
6.
Sa se genereze oglinditul numarului N. (daca N=1987 atunci oglinditul va fi 7891)
7.
Folosind problema de mai sus, stabiliti daca numarul N este palindrom.

9.

L11. Instructiunea WHILE


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.)

Instructiunea WHILE
Sintaxa :

while (expL) instructiune;

Efect
1.
2.
3.

Se evalueaza expresia logica


Daca valoarea expresiei logice este 1 (adevarata) se executa instructiunea si se revine la pasul 1
daca valoarea expresiei logice este zero (falsa) se continua cu instructiunea de dupa punct-virgula

Observatii:

in esenta, cat timp valoarea expresiei logice este adevarata, se executa instructiunea
daca valoarea expresiei logice este falsa de la inceput atunci instructiunea nu se mai executa
daca WHILE trebuie sa repete mai mult de o instructiune, acestea se vor incadra intre acolade;
instructiunea WHILE se mai numeste repetitiva cu test initial sau conditionata anterior,
pentru ca intai verifica valoarea conditiei si apoi executa secventa ce trebuie repetata

Problema exemplu. Fie A si B doua valori naturale. Sa se simuleza impartirea cu rest a lui A la B (prin
scaderi repetate) si sa se determine catul si restul impartirii.
#include <iostream.h>

void main()
{//declararea
int A, B, C=0;
//citirea
cin>>A>>B;
//prelucrarea
while(A>=B) {A=A-B; C++;};
//Afisarea rezultatelor
cout<<"catul este :"<<C<<endl;
cout<<"restul este : "<<A;
}

Explicatii. Cand impartim pe A la B cautam de cate ori se cuprinde B in A, altfel spus cate scaderi ale lui
B din a se pot face.
Un tip e problema ce necesita folosirea instructiunii WHILE este prelucrarea unui sir de valori ce se
incheie cu zero.
Ideea : Se citeste fiecare valoare si daca este nenula se prelucreaza; Acest pas se repeta pana citim valoarea
zero. (Ex: 23, -4, 5, 12, 79, 0).
Codul corespunzator este:
cin>>x;
While (x!=0) { //prelucrez valoarea X citita;
..............................
//citesc urmatoarea valoare din sir
cin>>x;};

Probleme ce folosesc acest algoritm pot umari:

numarul de valori din sir


valoarea maxima/minima
numarul de aparitii a unei valori K

10.

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,

11.1.

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.

11.2

L13. Conversia unui numar din baza B in baza 10


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;

11.3

L12. Sirul lui Fibonacci


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 (mereu trebuie memorata noua pereche formata ultimile doua valori determinate)
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;}

11.4

L11. Cmmdc. Cmmmc


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.

11.5

L10. Algoritmi fundamentali. Divizibilitate. N este prim?


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.

11.6

L9. Algoritmi fundamentali. Siruri de numere


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 saunu.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.

11.7

L8. Algoritmi fundamentali. Prelucrarea cifrelor unui


numar natural
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);

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