Documente Academic
Documente Profesional
Documente Cultură
Anexa Laborator 1 PDF
Anexa Laborator 1 PDF
Introducere în programare
Algoritm
Obiectele unui algoritm
Date
Constante
Variabile
Expresii
Operaţii specifice unui algoritm şi fluxul de execuţie al
acestora
Scheme logice
Simboluri grafice corespunzătoare operaţiilor
Exemple de algoritmi rezolvaţi în schemă logică
Pseudocod
Codificări corespunzătoare operaţiilor
Exemple de algoritmi descrişi în pseudocod
Probleme propuse şi rezolvate
Introducere în programare
Să considerăm următorul exemplu. Se defineşte funcţia F(x), unde x este număr real, astfel:
x2-2, x<0
F(x)= 3, x=0
x+2, x>0
Se cere să se scrie un program care să calculeze valoarea acestei funcţii pentru următoarele
100 de valori ale lui x: x = {-3, 0,1,7, 2.23, etc} – 100 valori.
Pentru a putea rezolva această cerinţă trebuie să vedem mai întâi care sunt etapele
rezolvării unei probleme utilizând un program informatic.
În cadrul acestui capitol ne vom ocupa de primele două etape, şi anume cea de formulare a
problemei şi cea de elaborare a algoritmului, pentru ca pe parcursul următoarelor capitole
să detaliem modalităţile de implementare a programelor utilizând limbajul de programare C.
Să revenim acum la problema noastră şi să parcurgem prima etapă, cea de formulare clară a
problemei:
datele disponibile sunt cele 100 de valori de intrare x
prelucrări necesare sunt calculul lui F(x) pentru cele 100 de valori ale lui x
rezultatele dorite sunt cele 100 de valori ale lui F(x) calculate prin prelucrări.
În acest moment putem spune că ştim foarte bine ce avem de făcut. Urmează să vedem mai
departe cum anume facem aceasta.
Pentru a trece la etapa a doua a rezolvării problemei nostre vom detalia în cele ce urmează
noţiunea de algoritm precum şi obiectele acestuia.
Algoritm
Algoritm - succesiune de etape ce se poate aplica mecanic pentru rezolvarea unei clase
de probleme.
Date
Principalele obiecte ale unui algoritm sunt datele. Ele pot fi:
Date de intrare - care sunt cunoscute
Date de ieşire - rezultate furnizate
După tipul lor, datele pot fi:
Întregi: 2, -4
Reale: 3.25
Logice: true şi false – adevărat şi fals
Caracter: ‘y’
Şir de caractere: “ab23_c”
Constante
În cadrul unui algoritm pot apare constantele, ce sunt date conţinute în program fără a fi
citite sau calculate. Un astfel de exemplu este constanta π din matematică.
Variabile
Programele, şi implicit algoritmii, manipulează (procesează) date. O variabilă este utilizată
pentru a stoca (a păstra) o dată. Se numeşte variabilă pentru că valoarea stocată se poate
schimba. Putem spune că are un nume unic şi poate avea conţinut diferit. Mai precis, o
variabilă este o locaţie de memorie care are un nume şi care păstrează o valoare de un
anumit tip.
pi 3.1415 double
Orice variabilă are un nume, conţine o valoare declarată de un anumit tip, valoare memorată mereu la o
aceeaşi adresă de memorie
De exemplu, în problema propusă anterior, putem păstra valorile datelor de intrare (x1, x2,
x3....) într-o variabilă numită x, care va lua pe rând fiecare din aceste valori de intrare.
Variabila x este de tip real, se află în memorie de exemplu la adresa 0xFF32 (adresă care
rămâne fixă) şi poate avea valoarea 3 la un moment dat.
În mod analog, rezultatele ( F(x1), F(x2), F(x3), ...) le vom stoca într-o variabilă F tot de tip
real.
Expresii
Expresiile sunt construite utilizând constante, variabile şi operatori. Ele pot fi de mai multe
tipuri, la fel ca şi datele: 3*x+7, x<y, etc
Operatorii utilizaţi sunt cei matematici (+, - , *, /, mod – restul împărţirii întregi), relaţionali
(<, >, <=, >=, != - diferit, == - comparaţie la egalitate), logici (şi – ambele adevărate, sau – cel
puţin una adevărată, not – negarea unei expresii).
Secvenţa este cea mai întâlnită, în cadrul ei instrucţiunile sunt executate în ordinea în care
sunt scrise, de sus în jos, secvenţial.
Să presupunem că vrem să calculăm funcţia F(x) din exemplu pentru toate numerele întregi
de la 1 la 1000. Pentru aceasta ar trebui să folosim o structură repetitivă (care mai poate fi
numită şi ciclu, buclă sau iteraţie) pentru a realiza una sau mai multe operaţii ce se repetă
(în acest caz calculul unei valori). La acestea sunt bune calculatoarele! Totuşi, ţine de
priceperea noastră să scriem astfel de algoritmi, ce conţin structuri repetitive care să poată
uşura foarte mult rezolvarea unei clase întregi de probleme) nu doar pentru o valoare fixă, ci
pentru orice număr real şi pentru oricâte numere!!
Schemele logice sunt reprezentări grafice ale algoritmilor. Fiecărei operaţii îi corespunde un
simbol grafic:
START STOP
T
var = expresia
Atribuirea:
Se evaluează expresia, apoi se atribuie valoarea expresiei variabilei din membrul
stâng
Operaţia de intrare: programatorul preia de la tastatură una sau mai multe valori
(intrări)
Citeste x
Operaţia de intrare:
Prin operaţia de citire (denumită şi operaţia de intrare) se preiau succesiv valori de
la tastatură şi se asociază, în ordine, variabilelor specificate.
Scrie x
Operaţia de ieşire:
Operaţia de scriere (denumită şi operaţia de ieşire) presupune evaluarea în ordine a
expresiilor specificate şi afişarea pe ecran a valorilor lor pe aceeaşi linie.
Acţiuni nedetaliate: un bloc de operaţii nedetaliat
Bloc
Bloc operaţii:
Se execută operaţia specifică blocului, fără ca această operaţie să fie detaliată. Este
utilizat în general pentru operaţii mai complexe, pentru a nu încărca schema logică
principală. Acest bloc va fi detaliat după realizarea schemei logice principale.
Exemplu: dacă vrem să afişăm primele n numere prime, putem avea un bloc de
operatii nedetaliat care testează dacă un număr este prim sau nu.
Secvenţial
Operaţie 1
Operaţie 2
.
.
.
Operaţie n
Secvenţa
Se execută în ordine Operaţie 1, apoi Operaţie 2, ş.a.m.d. până la Operaţie n.
Decizia
DA NU
(Adevărat) (Fals)
Conditie
Decizia
Se evaluează Condiţie;
Dacă valoarea Condiţiei este adevărat, atunci se merge pe ramura DA;
Dacă valoarea Condiţiei este fals, se se merge pe ramura NU.
DA NU
NU
Conditie Conditie
DA
Forma 1 Forma 2
Forma 1:
Se evaluează Condiţie;
Dacă valoarea Condiţiei este adevărat, atunci se execută instrucţiunea
sau instrucţiunile din Blocul DA;
Dacă valoarea Condiţiei este fals, nu se petrece nimic.
Forma 2:
Se evaluează Condiţie;
Dacă valoarea Condiţiei este adevărat se execută instrucţiunea sau
instrucţiunile din Blocul DA;
Dacă valoarea Condiţiei este fals se execută instrucţiunea sau
instrucţiunile din Blocul NU.
Bucla
DA
Conditie Bloc DA
NU
Bloc
Bucla
DA
Conditie
NU
Iniţializare
Bucla
NU
x2-2, x<0
F(x)= 3, x=0
x+2, x>0
Să se scrie un program care să calculeze valoarea acestei funcţii pentru 100 de valori ale lui
x.
Rezolvare:
A două etapă a rezolvării acestei probleme este elaborarea algoritmului ce implică analiza
detaliată a problemei:
Date:
x - valoare reală preluată de la consolă
Rezultate:
y - valoare reală care va fi afişată pe ecran (însoţită de un text explicativ)
Principalele etape de rezolvare
citirea datelor (se presupun corecte)
calculul valorii lui y în funcţie de intervalul în care se încadrează valoarea x citită
repetăm aceste etape pentru cele 100 de valori ale lui x.
Pentru a şti câte valori am citit vom folosi o variabilă aşa numită contor (deoarece
contorizează, numără). Este o variabilă întreagă şi o vom numi i. Ea porneşte cu valoarea
iniţială 0 (atenţie! Să nu uităm acest pas, este important!) şi la fiecare valoare citită îi vom
mări valoarea cu 1. Vom continua citirile atâta timp cât i va fi mai mic decât 100.
i =0
i =i+1
DA DA
i < 100 Citeste x x<0 Scrie y=x*x-2
x2-2 2222222
NU 222222 NU
2
STOP DA
x == 0 Scrie y=3
2222222
NU
Scrie y=x+2
3xx2222222
2. Analiza detaliată
Date:
2 valori preluate de la consolă:
v - valoare întreagă, strict pozitivă
p - valoare reala, pozitivă (majorare) sau negativă (diminuare)
Rezultat:
r - valoare reală, strict pozitivă, afişată pe ecran (însoţită de un text explicativ)
Principalele etape de rezolvare
citirea datelor (se presupun corecte)
calculul valorii actualizate cu formula v + v * p / 100 sau v * (1 + p / 100)
afişarea rezultatului
START
T
Citeste v, p
r=v+v*p
Scrie “Valoarea
actualizătă este ”, r
STOP
Pentru problemele care urmează vom oferi doar schema logică ce descrie algoritmul.
Problema 3: Una dintre cele mai simple probleme este citirea şi scrierea unei valori reale.
Date de intrare: x variabilă reala
Date de ieşire: acelaşi x.
În acest caz rezultatul este chiar data de intrare.
START
T
Citeste x
Scrie x
STOP
Problema 4: Rezolvarea ecuaţiei de grad 1: ax+b=0. Atenţie la cazurile speciale: a egal zero
şi/sau b egal zero!
Date de intrare: a şi b, variabile reale
Date de ieşire: x, variabilă reală
START
T
Citeste a,b
DA DA Scrie
a=0 b=0 “Infinitate
de solutii”
NU NU
x = -b / a Scrie
“Nu exista
solutii”
Scrie x
STOP
Problema 5: Să se afişeze suma primelor n numere naturale, n citit de la tastatură.
Date de intrare: n, variabilă întreagă
Date de ieşire: s, variabilă întreagă pozitivă ce stochează suma primelor n numere naturale
Variabile auxiliare: i, variabilă naturală de tip contor
START
T
Citeste n
s=0
i =0
i=i+1
DA
i<n s=s+i
NU
Scrie s
STOP
Problema 6: Algoritmul lui Euclid care determină cel mai mare divizor comun a doi întregi,
prin împărţiri repetate.
Date de intrare: a şi b, variabile întregi, pozitive. Se consideră că a este mai mare ca b.
Date de ieşire: cmmdc care este calculat în b.
Variabile auxiliare: r, variabilă naturală ce păstrează restul împărţirii lui a la b.
Atenţie! Dacă la final vrem să afişăm ceva de genul „Cel mai mare divizor comun al
numerelor: ” şi vrem să urmeze valorile iniţiale pentru a şi respectiv b, nu vom putea face
acest lucru deoarece valorile de intrare ale lui a şi b se pierd, ele modificându-se pe
parcursul execuţiei algoritmului.
Pentru a rezolva această problemă, vom păstra aceste valori iniţiale în două variabile
auxiliare: copie_a şi copie_b, iar la final vom afişa valorile din aceste două variabile.
START
T
Citeste a,b
r=a%b
DA a=b
r>0 b=r
r=a%b
NU
Scrie“cmmmdc
este ”, b
STOP
Pseudocod
Operaţia Pseudocod
Start start
Terminare stop.
Atribuire variabila=valoare;
Vom face următoarea convenţie: liniile ce conţin instrucţiuni care se execută în interiorul
unei bucle sau a unei decizii vor fi indentate (scrise deplasat în interior cu cateva spaţii) faţă
de linia pe care începe bucla sau decizia de care aparţin, pentru a pune în evidenţă execuţia
acestora în cadrul buclei (deciziei).
O altă posibilitate de a marca şi mai puternic este aceea de a grupa aceste linii într-un bloc
unitar utilizând acolade:
{
instrucţiune 1
instrucţiune 2
….
instrucţiune 3
}
Această ultimă convenţie este foarte asemănătoare cu ceea ce vom întâlni în limbajul C.
O altă observaţie este legată de simbolul punct şi virgulă „;”, ce apare la sfârşitul
instrucţiunilor. În limbajul C prezenţa acestuia este obligatorie, de aceea, pentru a uşura
trecerea de la pseudocod la C l-am introdus şi în pseudocod, fără însă ca aici prezenţa lui să
fie neapărat obligatorie. Totuşi, în cele ce urmează vom urmări utilizarea acestuia.
start
pentru i de la 0 la 100 cu pasul 1
citeste x;
daca x < 0
scrie x * x – 2;
altfel
daca x = 0
scrie 3;
altfel scrie x + 2;
stop.
start
citeste v, p;
r = v + v * p;
scrie r;
stop.
start
citeste x;
scrie x;
stop.
start
citeste a,b;
daca a = 0
daca b = 0
scrie “Ecuatia are o infinitate de solutii”;
altfel
“scrie Ecuatia nu are nici o solutie”;
altfel
x = -b / a;
scrie x;
stop.
start
citeste n;
s = 0;
pentru i de la 0 la n cu pasul 1
s = s + i;
scrie s;
stop.
Problema 6: Algoritmul lui Euclid care determină cel mai mare divizor comun a doi întregi,
prin împărţiri repetate:
start
citeste a,b;
r = a mod b;
atata timp cat r > 0
a = b;
b = r;
r = a mod b;
scrie b;
stop.
Probleme propuse:
Indicaţie: Atenţie! Trebuie să folosim o variabilă auxiliară. Nu funcţionează a=b şi apoi b=a
deoarece deja am pierdut valoarea iniţială a lui a!
Indicaţie: Atenţie la cazurile speciale! Dacă a este 0 ecuaţia devine ecuaţie de gradul 1!
O altă variantă este cea în care valorile variabilelor nu se modifică ci doar se afişează aceste
valori în ordine crescătoare:
Indicaţie: Vom folosi o variabilă auxiliară p în care vom calcula produsul parţial.
O altă modalitate este cea în care produsul parţial este actualizat la fiecare pas, fără a mai fi
calculat de fiecare dată de la 1:
Indicaţie: Vom folosi o variabilă auxiliară c în care vom calcula rând pe rând cifrele. Pentru
aceasta vom lua ultima cifră a lui ca rest al împărţirii lui n la 10, după care micşorăm n
împărţindu-l la 10 pentru a ne pregăti pentru a calcula următoarea cifră, şamd.
Indicaţie: Vom folosi o variabilă auxiliară c în care vom calcula rând pe rând cifrele ca în
problema anterioară, şi vom construi inversul pe măsură ce calculăm aceste cifre.
Indicaţie: Pentru aceasta vom împărţi numărul pe rând la numerele de la 2 la radical din n
(este suficient pentru a testa condiţia de prim, după această valoare numerele se vor
repeta). Dacă găsim un număr care să-l împartă exact vom seta o variabilă auxiliară b
(numită variabila flag, sau indicator) pe 0. Ea are rolul de a indica că s-a găsit un număr care
divide exact pe n. Iniţial presupunem că nu există un astfel de număr, şi deci, b va avea
valoarea 1 iniţial.
Indicaţie: Pentru aceasta vom împărţi numărul pe rând la numerele începând cu 2. Dacă
găsim un număr care să-l împartă exact vom împărţi pe n de câte ori se poate la numărul
găsit, calculând astfel puterea. În modul acesta nu va mai fi necesar să testăm că numerele
la care împărţim sunt prime!
Problema 10. Să se afişeze toate numerele naturale mai mici decât 10000 care se pot
descompune în două moduri diferite ca sumă de două cuburi.
Indicaţie: Această problemă prezintă foarte bine avantajul utilizării unui calculator în
rezolvarea anumitor probleme. Calculăm, pe rând, suma de cuburi a perechilor de numere
de la 1 la 21 (cel mai apropiat întreg de radical de ordin 3 din 10000). Căutăm apoi, pentru
fiecare sumă, o a doua pereche a cărei sumă de cuburi este aceeaşi. Dacă este o pereche
diferită de prima, afişăm numerele.
Indicaţie: Vom utiliza două variabile, max şi min pe care le iniţializăm cu o valoare foarte
mică şi respectiv cu o valoare foarte mare. Vom compara pe rând valorile citite cu max şi
respectiv cu min, iar dacă găsim o valoare mai mare, respectiv mai mică decât acestea
modificăm max (sau min, după cum e cazul) la noua valoare maximă, respectiv minimă.
Problema 12. Se dă o secvenţă de n numere întregi pozitive. Să se afişeze cele mai mari
numere de 2 cifre care nu se află în secvenţa respectivă.
Indicaţie: În cadrul acestei probleme şi a următoarei vom folosi o structură numită vector.
Aceasta este utilă atunci când trebuie să memorăm ca date mai multe valori. Numărul
acestor valori poate fi variabil iar ele vor fi păstrate sub un acelaşi nume, la adrese
consecutive de memorie. Accesarea unei anumite valori se face folosind un index. De
exemplu, dacă avem mai multe valori întregi, vom folosi un vector de numere întregi, v.
Pentru a accesa prima valoare citită vom folosi notaţia v[0], pentru a doua v[1], şamd.
În acest caz vom folosi un vector ca variabilă auxiliară în care vom ţine minte dacă un număr
de două cifre a fost citit de la tastatură (v[nr] este 0 dacă nr nu a fost citit şi v[nr] devine 1
dacă nr a fost citit de la tastatură). Iniţial, toate valorile din vector sunt 0.
Pentru a afla cele mai mari numere de două cifre care nu sunt în secvenţa citită vom
parcurge vectorul v de la coadă (99) la cap până întâlnim două valori zero.
Atenţie! În cazul în care nu există una sau două valori de două cifre care să nu aparţină
secvenţei citite nu se va afişa nimic!
Problema 13. Se dă o secvenţă de n numere întregi, ale căror valori sunt cuprinse în
intervalul 0-100. Să se afişeze valorile care apar cel mai des.
Indicaţie: Vom utiliza de asemenea un vector în care vom ţine minte de câte ori a apărut
fiecare valoare de la 0 la 100 – v[nr] reprezintă de câte ori a fost citit nr. Iniţial toate valorile
din vector sunt 0. Vom determina apoi valoarea maximă din acest vector, după care, pentru
a afişa toate numerele care apar de cele mai multe ori mai parcurgem încă o dată vectorul şi
afişăm indicii pentru care găsim valoarea maximă.