Sunteți pe pagina 1din 9

C apito lul I:

Algoritmi

I . 1 . G e ne ra l i tã Ń i de sp r e a l go r i tm i

I .1 .1 . N o Ń i u ne a d e a l g o r i t m

Aşa cum deja ştiŃi, pentru a rezolva o problemă cu ajutorul calculatorului


trebuie să scriem un program într-un anumit limbaj de programare. Dar înainte de
a ajunge la program, trebuie să proiectăm rezolvarea problemei.
DefiniŃie:
Succesiunea etapelor rezolvării unei probleme, în ordinea parcurgerii lor, prin
care se prelucrează un set de date de intrare, în scopul obŃinerii unor date de ieşire
(rezultate), se numeşte algoritmul problemei.
Etapele rezolvării se mai numesc şi paşii algoritmului.
Orice informaŃie, de orice gen, care descrie un anumit fenomen, eveniment
etc., poate fi codificată sub forma unei date. Aşa cum reiese şi din definiŃia de mai
sus, în cadrul unui algoritm întâlnim două tipuri de date:
 Datele de intrare trebuie să fie cunoscute la "intrarea în algoritm",
adică la începutul execuŃiei algoritmului.
 Datele de ieşire sunt de fapt rezultatele problemei pe care o rezolvă
algoritmul respectiv, rezultate obŃinute în timpul execuŃiei
algoritmului, prin prelucrarea datelor de intrare.
Orice algoritm trebuie să îndeplinească câteva cerinŃe fundamentale:
a) să fie cât mai general, adică să acopere toate situaŃiile care pot interveni
în rezolvarea problemei respective;
b) să fie bine-definit. Altfel spus, cerinŃele problemei să fie formulate clar,
fără ambiguităŃi, iar datele de care dispune algoritmul să fie suficiente pentru
rezolvarea problemei;
c) să fie finit. Algoritmul unei probleme trebuie proiectat de aşa manieră
încât să existe certitudinea că la un moment dat se va încheia cu succes execuŃia
lui, obŃinându-se toate soluŃiile problemei;
d) să fie rezolvabil. În traducere, orice algoritm trebuie să aibă cel puŃin o
soluŃie.

3
I .1 . 2 . O b i e c t e l e c u c a r e l u c r e a z ã a l g o r i t m i i

Orice algoritm foloseşte anumite "obiecte" asupra cărora sunt permise


anumite operaŃii. Aceste obiecte sunt de două tipuri: date şi expresii.
Ex e mp l u :
Să încercăm să ne imaginăm un algoritm pentru traversarea unei străzi într-o
intersecŃie semaforizată. Prima acŃiune pe care o executăm în cadrul algoritmului este
aceea de a ne uita la culoarea semaforului. Creierul uman înregistrează culoarea
semaforului ca pe o informaŃie. Prin prelucrarea acestei informaŃii, hotărâm ce acŃiune
executăm în continuare: dacă semaforul arată "verde", atunci ne angajam în traversarea
străzii, în caz contrar… mai aşteptăm. InformaŃia numită "culoarea semaforului" este un
obiect cu care lucrează algoritmul pentru traversarea străzii. Aşa cum am spus mai înainte,
orice informaŃie se poate codifica (reprezenta) sub forma unei date. Astfel, în exemplul
nostru, informaŃia numită culoarea semaforului poate fi reprezentată sub forma unui şir de
caractere cuprins între ghilimele: “rosu” respectiv “verde”. De ce este necesară această
codificare ? Dacă ar fi să elaborăm un program pentru algoritmul de traversare a străzii,
trebuie să ne gândim că un calculator nu poate percepe culorile aşa cum o face creierul
uman ! Calculatorul trebuie să memoreze informaŃia numită culoare sub forma unei date,
pe care să o poată prelucra în maniera în care ştie el să gândească.

Datele unui algoritm pot fi de două tipuri: constante şi variabile.

Constante
DefiniŃie:
O constantă este o dată a cărei valoare nu se modifică în timpul execuŃiei
algoritmului.
Constantele sunt de mai multe tipuri:
a) Constantele întregi. Sunt numere din mulŃimea Z, adică numere întregi
cu sau fără semn. Exemple: 232, +87, -1405.
b) Constante reale. Sunt valori raŃionale, cu virgulă zecimală, dar care au
un număr finit de zecimale. Mai notăm că virgula zecimală se reprezintă prin
caracterul "punct". Exemple: 2.34, -45.26
c) Constante caracter. Sunt caractere cuprinse între apostrofuri. Acestea
pot fi litere mari şi mici, caractere-cifră şi caractere speciale. Exemple: 'A', 'm',
'$', '9' etc.
d) Constantele şir de caractere. Sunt şiruri de caractere cuprinse între
ghilimele, care pot conŃine orice caractere, inclusiv caractere speciale şi caracterul
"spaŃiu ". Exemple: “program”, “Borland C++ 7.0”, ”AB#7”, etc.
În programe vom folosi foarte mult aşa-numitele “constante întregi cu
sens logic (boolean)”. Ce rol au acestea ? În cadrul unui algoritm putem întâlni

4
condiŃii, care pot fi îndeplinite sau nu, şi în funcŃie de care se vor decide acŃiunile
următoare. Orice condiŃie se caracterizează printr-o aşa numită "valoare de
adevăr", care ne spune dacă respectiva condiŃie este îndeplinită sau nu. Astfel, o
condiŃie poate avea valoarea de adevăr ”ADEVĂRAT” (condiŃie îndeplinită,
adevărată), sau ”FALS” (condiŃie neîndeplinită, falsă). Deoarece în limbajul C++
nu există un tip de date care să desemneze valorile logice, vom simula cele două
valori de adevăr posibile ale unei condiŃii prin numerele întregi 1 respectiv 0. Mai
exact, numărul întreg 1 corespunde valorii de adevăr ”ADEVĂRAT”, iar numărul
întreg 0 identifică valoarea de adevăr ”FALS”. Mai multe detalii pe această temă
veŃi învăŃa în capitolele următoare.

Variabile

DefiniŃie:
Numim variabilă, un obiect caracterizat prin trei atribute, tip, adresă şi
valoare, cu proprietatea că atributul valoare este modificabil.

Ex e mp l u :
Fie funcŃia matematică f:[-10,10] → R, f(x)= 2x+1.
Aceasta este definită prin: domeniu de definiŃie [-10,10] (mulŃimea valorilor pe
care le poate lua x), codomeniul R (mulŃimea valorilor funcŃiei f(x)) şi legea de asociere
f(x)= 2x+1. Despre x putem spune că poate lua orice valoare din domeniu, şi fiecărei
valori a lui x îi corespunde o valoare a funcŃiei. De exemplu, pentru x=-3 obŃinem
f(-3)=2·(-3)+1= -5, pentru x=2 avem f(2)=5 etc. Astfel, x este o variabilă pentru că
valoarea sa se poate modifica în orice moment. Mai exact, dacă am proiecta un algoritm
pentru calculul valorilor funcŃiei de mai sus, atunci valoarea lui x s-ar modifica în cursul
execuŃiei algoritmului. După cum observaŃi, sensul noŃiunii de variabilă este cel cunoscut
din matematică.

Tipul unei variabile stabileşte mulŃimea valorilor pe care le poate primi


variabila respectivă. La nivel de algoritmi vom folosi patru tipuri, cele pe care le
cunoaşteŃi deja din lecŃia "Constante". Le sintetizăm în continuare, dar fără a
insista prea mult asupra lor, deoarece le vom relua în capitolul III, în care vom
prezenta elementele de bază ale limbajului C++.
Denumirea tipului Cum pot fi valorile variabilelor de tipul respectiv
Tipul întreg Numere întregi cu sau fără semn
Tipul real Numere reale (cu virgulă zecimală reprezentată prin caracterul
"punct ")
Tipul caracter Caractere cuprinse între apostrofuri
Tipul şir de caractere Şiruri de caractere cuprinse între apostrofuri

La fel ca şi în matematică, orice variabilă trebuie să aibă un nume, căruia


îi vom spune de acum încolo identificator de variabilă. Evident în cadrul unui
algoritm nu pot exista două variabile cu acelaşi identificator.

5
Expresii
În scopul efectuării calculelor, algoritmii folosesc expresii. O expresie
este alcătuită dintr-unul sau mai mulŃi operanzi legaŃi între ei prin operatori.
Operanzii reprezintă valorile care intră în calcul. Ei pot fi constante şi
variabile. Operatorii desemnează operaŃiile care se execută în cadrul expresiei.
Vom vedea mai târziu că într-un program C++ unii dintre operatori se
simbolizează altfel decât îi cunoaştem din matematică. Desigur că atunci când
scriem un algoritm pe hârtie putem nota operatorii cum vrem. Chiar dacă
deocamdată ne ocupăm numai de algoritmi, vom introduce de la bun început nişte
notaŃii apropiate de sintaxa limbajului C++, pentru a evita riscul unor confuzii
ulterioare.
În timpul execuŃiei algoritmului expresiile sunt evaluate. Evaluarea unei
expresii are loc astfel: se înlocuiesc variabilele cu valorile lor şi se efectuează
calculele, obŃinându-se astfel valoarea expresiei.
Expresiile se împart în două categorii: expresii aritmetice şi expresii
logice. Principalele categorii de operatori sunt: operatori aritmetici, logici şi
relaŃionali.

Expresii aritmetice
Sunt cele care efectuează operaŃii aritmetice având ca rezultat un număr.
În continuare vom nota operatorii aritmetici aşa cum sunt ei definiŃi în limbajul
C++. Mai mult, vom încerca să vă obişnuim de pe acum să respectaŃi câteva reguli
pe care le impune acest limbaj în ceea ce priveşte folosirea operatorilor.
Operatorii aritmetici sunt:
+ (adunare) * (înmulŃire) – (scădere) / (împărŃire)
Ex e mp l u :
a + b
• Expresia din matematică se scrie într-un program sub forma (a+b)/2.
2
Să vedem cum procedează calculatorul pentru a evalua expresia în cazul în care
variabilele au valorile a=5 şi b=7: aşa cum am spus, se înlocuiesc variabilele cu valorile
lor şi se efectuează calculele, obŃinându-se valoarea expresiei; deci valoarea expresiei
(a+b)/2 este (5+7)/2, adică 6. Operatorul "/" a înlocuit linia de fracŃie.
Parantezele sunt absolut necesare. Există o aşa numită prioritate a operatorilor, ce
stabileşte ordinea în care se execută operaŃiile în timpul evaluării unei expresii. Conform
acesteia, se execută mai întâi împărŃirile şi înmulŃirile, apoi adunările şi scăderile. Aşadar,
b
în absenŃa parantezelor, expresia a+b/2 este echivalentă cu "formula" a + .
2

Expresii logice (booleene)


Aşa cum am mai spus, în algoritmi întâlnim deseori condiŃii. O condiŃie
poate fi scrisă sub forma unei expresii logice. Valoarea unei expresii logice

6
reprezintă valoarea de adevăr a condiŃiei aferente, şi poate fi “ADEVĂRAT”
(condiŃie îndeplinită, adevărată) şi “FALS” (condiŃie neîndeplinită, falsă). Am
arătat în lecŃia “Constante” că în limbajul C++ vom simula cele două valori de
adevăr posibile ale unei condiŃii prin numerele întregi 1 respectiv 0. Astfel, o
expresie logică poate avea valoarea:
− 1, în cazul în care condiŃia pe care o defineşte este adevărată;
− 0, în situaŃia în care condiŃia pe care o descrie este falsă.
O expresie logică este construită de obicei cu ajutorul operatorilor
relaŃionali. Am precizat deja faptul că în limbajul C++ unii operatori sunt
simbolizaŃi diferit faŃă de notaŃia cunoscută din matematică. Pentru a vă obişnui de
la bun început cu sintaxa limbajului C++, vom defini încă de pe acum operatorii
aşa cum sunt ei implementaŃi în limbaj. Operatorii relaŃionali ai limbajului C++
sunt: "==" (operatorul de testare al egalităŃii), "<" ("mai mic"), ">" ("mai mare"),
"<=" ("mai mic sau egal"), ">=" ("mai mare sau egal"), "!=" ("diferit").
Exemplu:
• Dacă a şi b sunt variabile numerice (întregi sau reale), a− − 10>=b este o
expresie logică: pentru a=12 şi b=5, expresia are valoarea 0, corespunzătoare valorii de
adevăr FALS ("12-10>=5 ? nu "); în schimb, pentru a=8 şi b=6, expresia are valoarea 1,
corespunzătoare valorii de adevăr ADEVĂRAT ("8-10>=6 ? nu")
Mai multe expresii logice pot fi "combinate" cu ajutorul operatorilor
logici, obŃinându-se o aşa numită "expresie logică compusă". Expresiile logice
"elementare" ce alcătuiesc expresia compusă pot fi scrise între paranteze. În mod
implicit, operaŃiile ce apar în cadrul unei expresii, se execută într-o anumită
ordine, dată de aşa-numita “prioritate a operatorilor”. Despre acest subiect am
pomenit deja în cadrul exemplului dat în paragraful “Expresii aritmetice”,
precizând atunci faptul că rolul parantezelor într-o expresie este tocmai acela de a
schimba ordinea implicită în care se execută operaŃiile. Operatorii logici pe care-i
vom folosi în acest capitol sunt ŞI, SAU (pentru aceştia nu vom introduce încă
notaŃia lor din limbajul C++, preferând deocamdată aceste două cuvinte din limba
română care sunt mult mai sugestive).
Exemplu:
Fie a şi b două variabile de tip întreg. CondiŃia ca “numerele a şi b să fie ambele
pozitive”, poate fi scrisă astfel:
• a>0 ŞI b>0
• (a>0) ŞI (b>0)
În a doua formă, expresiile elementare ce compun expresia logică compusă, adică
“a>0” şi “b>0” au fost cuprinse între paranteze rotunde. În cazul de faŃă, parantezele nu
sunt necesare, deoarece în mod implicit compilatorul limbajului C++ efectuează operaŃiile
în ordinea în care dorim: mai întâi evaluează expresiile elementare “a>0” respectiv “b>0”,
apoi aplică “ŞI logic” între valorile acestora.
Pentru ca expresia "a>0 ŞI b>0" să fie adevărată, este necesar ca expresiile
componente "a>0", "b>0" să fie adevărate în acelaşi timp.

7
− pentru a=3, b=8, expresia are valoarea 1 (cu sens de ”ADEVĂRAT”); ("3>0
ŞI 8>0 ? da");
− pentru a=4, b=-2, expresia are valoarea 0 (cu sens de ”FALS”); (nu este
"b>0)".
• a>0 SAU b>0 → descrie condiŃia ca cel puŃin unul dintre numerele a, b să fie
pozitiv
Pentru ca expresia "a>0 SAU b>0" să aibă valoarea 1 (”ADEVĂRAT”), trebuie ca
cel puŃin una dintre expresiile "a>0", "b>0" să fie adevărată.
− pentru a=4, b=-2 expresia are valoarea 1 (”ADEVĂRAT”);
− pentru a=-3, b=-5 expresia are valoarea 0 (”FALS”).

I . 2 . R ep r e z e n t a r e a al go r i t m i l o r .
P s eu d o c o du l .
Aşa cum am spus deja, algoritmul unei probleme este alcătuit dintr-o
succesiune de paşi ce reprezintă etapele rezolvării problemei. În cadrul fiecărui pas
se execută una sau mai multe acŃiuni.
Scopul elaborării algoritmului unei probleme este acela de a scrie un
program într-un anumit limbaj de programare. Dar dacă avem de-a face cu o
problemă mai complexă, înainte de a scrie programul este bine să schiŃăm paşii
algoritmului. În acest scop avem la dispoziŃie o formă foarte accesibilă de
reprezentare a algoritmilor, şi anume pseudocodul.
Un limbaj pseudocod se prezintă sub formă de text şi se bazează pe nişte
aşa-numite cuvinte cheie. Fiecare cuvânt cheie identifică în mod unic un anumit tip
de acŃiune.
AcŃiunile algoritmului se reprezintă în pseudocod prin ceea ce numim
instrucŃiuni.
Ansamblul cuvintelor cheie împreună cu regulile care trebuie respectate
în folosirea lor, alcătuieşte ceea ce numim sintaxa limbajului-pseudocod.
Există o mare diversitate de limbaje-pseudocod. Practic, fiecare
programator îşi poate proiecta propriul pseudocod, definind cuvintele cheie ale
acestuia şi impunând nişte reguli de sintaxă.
În cele ce urmează vom folosi o variantă de pseudocod în care cuvintele
cheie provin din limba română, iar regulile de sintaxă sunt cele pe care le impune
limbajul C++. Deocamdată trebuie să reŃineŃi două dintre aceste reguli:
− asemeni limbajului C++, în pseudocod nu vom face deosebire între litere
mari şi litere mici;
− comentariile, prin care descriem pe scurt acŃiunile algoritmului
(instrucŃiunile pseudocodului), vor fi precedate de caracterele “//”.

8
I .2 .1 . P r i m u l e x e m p l u d e p s e u do c o d

Vom începe cu un exemplu foarte simplu: algoritmul pentru calculul ariei


unui triunghi cu formula A = b ⋅ h , unde b este o latură a triunghiului (baza), iar
2
h este înălŃimea corespunzătoare.
Să vedem ce instrucŃiuni ar trebui să execute programul scris după acest
algoritm, şi cum se reprezintă ele în pseudocod. Le vom enumera în ordinea
"derulării" lor.
Mai întâi calculatorul trebuie să preia valorile laturii bazei şi înălŃimii
triunghiului, pe care le va memora în nişte variabile simbolizate ca în formulă. Vom spune
aşadar "baza b şi înălŃimea h". Acestea sunt datele de intrare ale algoritmului. De ce se
utilizează variabile ? Un program eficient şi general este acela capabil să calculeze aria
oricărui triunghi, adică pentru orice valori ale bazei şi înălŃimii. Cu alte cuvinte, vrem ca
de fiecare dată când se execută, programul să poată calcula aria altui triunghi, pentru alte
valori ale bazei şi înălŃimii. Cum anume facem să se întâmple aşa ?
În timpul execuŃiei programului, vom introduce de la tastatură valorile bazei şi
înălŃimii, câvalori pe care calculatorul le va prelua şi le va memora în variabilele b
respectiv h. În sens figurat spus, "calculatorul citeşte datele de intrare de la tastatură ".
Această formulare, care parcă dă viaŃă calculatorului, este atât de consacrată în
informatică, încât o vom folosi permanent de acum încolo.
În pseudocod, o instrucŃiune de citire a datelor de intrare începe cu cuvântul cheie
"citeşte" urmat de numele variabilelor care se citesc separate prin virgulă, şi se încheie
cu caracterul "punct şi virgulă". În exemplul nostru această instrucŃiune este:
citeşte b,h;
Evident că puteam folosi două instrucŃiuni de citire, câte una pentru fiecare
variabilă:
citeşte b;
citeşte h;
De cele mai multe ori este necesar ca datele de intrare să respecte nişte condiŃii,
pe care calculatorul trebuie să le testeze. În exemplul nostru, după ce a preluat prin citire
de la tastatură valorile bazei şi înălŃimii (pe care le-a memorat în variabilele b şi h),
calculatorul trebuie să verifice dacă acestea sunt ambele pozitive (nu există triunghi cu
bază sau înălŃime negativă sau nulă). Altfel spus, condiŃia testată este "baza b mai mare ca
zero ŞI înălŃimea h mai mare ca zero". Evident, condiŃia respectivă va fi descrisă printr-o
expresie logică. În pseudocod, această instrucŃiune se reprezintă sub forma:
dacă (<condiŃie>)
Şi în ceea ce priveşte această instrucŃiune, am impus în pseudocod o regulă de
sintaxă a limbajului C++: condiŃia <condiŃie> se scrie între paranteze rotunde.
În exemplul nostru vom scrie:
dacă (b>0 ŞI h>0) atunci

9
CondiŃia "(b>0 ŞI h>0)" nu este altceva decât o expresie logică compusă,
alcătuită din două expresii elementare "legate" prin operatorul logic "ŞI".
În funcŃie de valoarea de adevăr a condiŃiei (adevărată sau falsă), calculatorul va
lua o decizie cu privire la ce va face în continuare, introducând astfel o ramificaŃie în
algoritm. Astfel cele două cazuri posibile sunt:
a) dacă această condiŃie este îndeplinită (adevărată), adică dacă expresia logică
"(b>0 ŞI h>0)" are valoarea 1, atunci calculatorul va putea calcula aria, pe care apoi ne-
o va "comunica";
b ⋅ h
 pentru calculul ariei trebuie să introducem formula matematică A = .
2
Cum anume ? Printr-o aşa-numită instrucŃiune de atribuire, pe care o scriem
astfel: A ←(b*h)/2;
Vom spune că variabilei A i se atribuie valoarea expresiei aritmetice (b*h)/2.
Să analizăm această atribuire:
− operanzii care apar sunt variabilele b, h şi constanta 2
− pentru operatorii de înmulŃire şi împărŃire folosim simbolurile deja definite:
"*" respectiv "/";
− simbolul "←" ("săgeată") reprezintă operatorul de atribuire;
− instrucŃiunea se execută astfel: în dreapta operatorului de atribuire,
calculatorul va înlocui variabilele b şi h cu valorile lor (preluate prin citire),
obŃinând astfel valoarea expresiei, pe care o va memora în variabila A; de
exemplu, dacă baza b este 5 iar înălŃimea h este 4, atunci expresia
aritmetică (b*h)/2 are valoarea (5*4)/2, adică 10, deci în variabila A se
va memora valoarea 10;
− la finele oricărei atribuiri punem "punct şi virgulă".
 după ce a determinat valoarea ariei A, calculatorul trebuie să ne-o comunice. Cum
anume ? Afişând-o pe monitor. Aceasta este o instrucŃiune de ieşire. În
pseudocod, vom folosi cuvântul cheie "scrie" urmat de numele variabilei a cărei
valoare se afişează, încheind instrucŃiunea cu "punct şi virgulă":
scrie A;

b) În cazul contrar celui de la a) (condiŃia nu este adevărată), calculatorul va


tipări un mesaj de eroare. Cazul contrar este simbolizat numai prin cuvântul cheie altfel
Pentru tipărirea unui mesaj utilizăm tot cuvântul "scrie", mesajul fiind cuprins
între ghilimele (este o constantă şir de caractere).
scrie "Date incorecte";
Acestea fiind spuse, putem scrie primul nostru pseudocod complet.
citeşte b,h;
dacă (b>0 ŞI h>0)
început
A ← (b*h)/2;
scrie A;
sfârşit
altfel
scrie "Date incorecte";
10
♦ CondiŃia din linia "dacă" împreună cu tot ce urmează, adică instrucŃiunile ce
reprezintă ramurile "DA" şi "NU", alcătuiesc aşa numita structură alternativă sau structură
de selecŃie.
♦ ObservaŃi că în cazul în care condiŃia "(b>0 ŞI h>0)" este adevărată, se vor
executa două instrucŃiuni. Luate împreună, cele două instrucŃiuni alcătuiesc o secvenŃă de
instrucŃiuni. Aşadar, două sau mai multe instrucŃiuni luate împreună, alcătuiesc ceea ce
numim o secvenŃă de instrucŃiuni. În pseudocod, dacă pe o ramură urmează o secvenŃă de
cel puŃin două instrucŃiuni, acestea vor fi cuprinse între cuvintele "început" şi
"sfârşit". În schimb, în situaŃia în care condiŃia nu este adevărată, se va executa o
singură instrucŃiune, deci nu se mai scrie "început" şi "sfârşit".
♦ Pseudocodul de mai sus poate fi simplificat. Nu este neapărat necesar să
memorăm valoarea ariei în variabila A, ci putem să o afişăm direct, ca expresie. Mai exact,
afişăm valoarea expresiei (b*h)/2. Iată aşadar că pe lângă valorile variabilelor se pot
afişa şi valori ale unor expresii.
citeşte b,h;
dacă (b>0 ŞI h>0)
scrie (b*h)/2 ;
altfel
scrie "Date incorecte";

11

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