Sunteți pe pagina 1din 13

TIPURI DE DATE

I. Clasificare
1. Tipul numeric
- nr. întregi - INT[-32768,32767], numere întregi cu cel mult 4 cifre
- LONG ±2.140.000.000, numere întregi cu cel mult 9 cifre
- nr reale – FLOAT, DOUBLE
2. Tipul caracter – CHAR {litere, cifre, alte simboluri}
Codul ASCII 0.........48.........57..............65................90............97...........122
...........‘0’.........’9’............’A’...............’Z’...........’a’............’z’
II. Operatori
1. Aritmetici {+, -, *, /,%}
- operează cu numere, iar rezultatul este tot numeric
- % furnizează restul împărțirii a două nr întregi; lucrează numai cu numere întregi
- a/b furnizează câtul împărțirii dacă cele două numere sunt întregi: 7/2=3
- a/b efectuează împărțirea cu rest (cu virgulă) dacă unul din operanzi este număr real: 7.0/2=3.5
- *, / și % au nivel de prioritate I, iar + și – au nivel de prioritate II
2. Relaționali{<, >, <=, >=, ==, !=}
- lucrează cu numere și caractere, iar rezultatul este logic (adevărat– 1 sau fals – 0)
- doi câte 2 sunt opuși (< cu >=, > cu <=, == cu !=)
- într-o expresie poate să apară un singur operator relațional
Ex: a<=x<=b este greșit; ea se scrie a<=x && x<=b
3. Logici {!, &&, ||}
- lucrează cu propoziții logice (expresii, construcții, condiții), iar rezultatul este tot logic
- ! are prioritate I, && are prioritate II, || are prioritate III
- a && b (a ȘI b) este adevărată numai când ambele propoziții (a și b) sunt adevărate
- a || b (a SAU b) este adevărată dacă cel puțin una din cele două propoziții este adevărată
- ! este operator unar (are nevoie de o singură propoziție)
- ! (p && q)  ! p || ! q
- ! (p || q)  ! p &&! q
4. De conversie explicită
- conversie la număr întreg: z = (int) (a/b); (cu a sau b număr real)
- conversie la număr real: z = (float) a/b; (cu a și b numere întregi)
- conversie la caracter: c=(char) x; (cu x număr natural ≤255)
Operatorul a % b
- a % b [0, b-1]
- a divizibil cu b  a%b==0
- a nu e divizibil cu b  a%b !=0
- a<b  a%b==a  a/b==0
- a - nr par  a % 2==0
a - nr impar  a % b!=0  a % 2==1
- a % 10 reține ultima cifră a lui a a / 10 elimină ultima cifră a lui a
a % 100 reține ultimele 2 cifre ale lui a a / 100 elimină ultimele 2 cifre ale lui a
a % 1000 reține ultimele 3 cifre ale lui a a / 1000 elimină ultimele 3 cifre ale lui a
................................................................... ...................................................................
- pentru un număr x de 4 cifre, x=abcde avem
e = x % 10 c = x / 100 % 10 a = x / 10000
d = x / 10 % 10 b = x / 1000
III. Funcții predefinite
1. sqrt(x) – determină radicalul lui x
2. floor (x) - determină partea întreagă a lui x (se mai poate utiliza (int) x)
3. abs(x) – determină modulul (valoarea absolută) unui număr întreg x de tip int
4. labs(x) – determină modulul (valoarea absolută) unui număr întreg x de tip long

1
5. fabs(x) – determină modulul (valoarea absolută) unui număr real x
Obs: Alte formule:
6. X este număr întreg  x==(int) (x)
7. X este pătrat perfect  sqrt(x)== (int) sqrt(x) sau sqrt(x)== floor (sqrt(x))

INSTRUCȚIUNI
I. Instrucțiuni pentru citire / scriere
cin>>arg1>> ...>>argn; cout<<arg1<< ... <<argn;
Ex: cin>>x>>y; cout<<x<<” “<<y;
cout<<”Suma numerelor “<<a<<” si “<<b<<” este “<<a+b<<endl;
II. Instrucțiunea de atribuire
identificator=expresie
Ex: x=2; y=y+1; z=a+b; z+=3; z+=i++; z+=++i;
III. Instrucțiunea de decizie
IF (condiție) set_instrucțiuni1; DACĂ condiție ATUNCI set_instrucțiuni1
[ELSE set_instrucțiuni2]; ALTFEL set_instrucțiuni2
Evaluare:
1. Testează condiția
2. Dacă condiția este adevărată, execută set_instrucțiuni1, iar dacă este falsă execută set_instrucțiuni2
Obs:
- dacă set_instrucțiuni conține cel puțin două instrucțiuni, acestea se vor încadra între { }
- ramura ELSE este facultativă
- înainte de ELSE se pune ‘;’
- set_instrucțiuni poate conține oricare din instrucțiunile Limbajului C++
IV. Instrucțiunea repetitivă cu contor
FOR (contor=vi; expresie1; expresie2) PENTRU contorvi,vf [,-1] EXECUTĂ
set_instrucțiuni; set_instrucțiuni
Mod de lucru:
1. Inițializează contorul cu vi (contor=vi) și mergi la 2
2. Testează expresie1 și mergi la 3
3. Dacă expresie1 este adevărată, execută set_instrucțiuni și mergi la 4, iar dacă nu, mergi la 5
4. Execută expresie 2 și mergi la 2
5. Sfârșit
V. Instrucțiunea repetitivă cu test inițial
WHILE (condiție) CÂT TIMP condiție EXECUTĂ
set_instrucțiuni; set_instrucțiuni
Evaluare:
1. Testează condiția și mergi la 2
2. Dacă condiția este adevărată execută set_instrucțiuni și mergi la 1, iar dacă condiția este falsă mergi la 3
3. Sfârșit
VI. Instrucțiunea repetitivă cu test final
DO REPETĂ
set_instrucțiuni; set_instrucțiuni
WHILE (condiție); PÂNĂ CÂND condiție
Evaluare:
1. Execută set_instrucțiuni și mergi la 2
2. Testează condiția și mergi la 3
3. Dacă condiția este adevărată mergi la 1, iar dacă este falsă mergi la 4
4. Sfârșit
Obs: pentru a transcrie condiție de la REPETĂ în cea de la DO...WHILE, condiție trebuie negată
De exemplu: REPETĂ ... PÂNĂ CÂND a>b devine DO ... WHILE (a<=b)

2
VII. Transformări în pseudocod
1. Transformare CÂT TIMP => REPETĂ
dacă condiție atunci
Cât timp condiție execută repetă
set instrucțiuni set instrucțiuni
până când ! condiție

2. Transformare REPETĂ => CÂT TIMP


repetă set instrucțiuni
set instrucțiuni cât timp ! condiție execută
până când condiție set instrucțiuni

3. Transformare PENTRU => CÂT TIMP


pentru contor  vi, vf execută contor  vi
set instrucțiuni cât timp contor ≤ vf execută
set instrucțiuni
contor  contor + 1

4. Transformare PENTRU => REPETĂ


pentru contor  vi, vf execută contor  vi
set instrucțiuni dacă contor ≤ vf atunci
repetă
set instrucțiuni
contor  contor + 1
până când contor > vf
VIII. Modele de probleme
1. Șir cu n numere întregi
a. prelucrare valori individuale b. prelucrare perechi consecutive (x,y) c. prelucrare triplete consecutive (x,y,z)
cin>>n; cin>>n>>x; cin>>n>>x>>y;
for(i=1;i<=n;i++) for(i=1;i<n;i++) for(i=1;i<n-1;i++)
{ { {
cin>>x; cin>>y; cin>>z;
<prelucrare x> <prelucrare (x,y)> <prelucrare (x,y,z)>
} x=y; x=y;
} y=z;
}
2. Șir de numere întregi terminat cu 0
a. prelucrare valori individuale b. prelucrare perechi consecutive (x,y) c. prelucrare triplete consecutive (x,y,z)
cin>x; cin>x; cin>x>>y;
while (x!=0) while (x!=0) while (x!=0)
{ { {
<prelucrare x> cin>y; cin>z;
cin>x; <prelucrare (x,y); <prelucrare (x,y,z);
} x=y; x=y;
} y=z;
}
3. Generarea tuturor valorilor dintr-un interval [a, b]
a. Generare valori individuale (i) b. Generare perechi de valori (x, y) c. Generare triplete de valori (x, y,z)
for (i=a;i<=b;i++) for (x=a;x<=b;x++) for (x=a;x<=b;x++)
<prelucrare i> for (y=a;y<=b;y++) for (y=a;y<=b;y++)
<prelucrare (x,y)> for (z=a;z<=b;z++)
<prelucrare (x,y,z)>
ALGORITMI FUNDAMENTALI
3
I. Prelucrarea cifrelor unui număr natural
while (n>0)
{
c=n%10; //reține ultima cifră
n=n/10; //elimină ultima cifră
<prelucrare c>; //prelucrează ultima cifră
}
Obs: - dacă se prelucrează câte două cifre simultan, condiția n>0 devine n>9
- pentru adăugarea cifrelor la sfârșitul unui număr (la dreapta, inversul, oglinda) se folosește formula:
inv=inv*10+c;
- pentru adăugarea cifrelor la începutul unui număr (la stânga) se folosește formula:
nr=f*c+nr;
f=f*10
II. Verificarea primalității unui număr natural n Varianta eficientă
p=0; OK=1;
for (i=1;i<=n;i++) if (n%2==0) OK=0;
if (n%i==0) p++; i=3;
if (p==2)<n este prim>; while (i<=sqrt(n) && OK)
[if (p!=2)<n nu este prim>;] if (n%i==0) OK=0;
else i=i+2;
III. Descompunerea unui număr natural (n) în factori primi (de forma dk)
d=2;
while (n>1)
{
k=0;
while (n%d==0)
{
n=n/d;
k=k+1;
}
if (k>0) <prelucrare d și/sau k>
d++;
}
IV. CMMDC(a, b)
while (a!=b)
if (a>b) a=a-b;
else b=b-a;
Obs: - la ieșirea din algoritm, cele două valori vor fi egale, oricare dintre ele reprezentând valoarea cmmdc;
- algoritmul lucrează numai pentru nr. naturale; pentru nr. întregi se va lucra cu modulul numerelor;
- algoritmul modifică valorile lui a și b, a.î. dacă mai avem nevoie de ele, trebuie să luăm copii ale lor;
- CMMMC se calculează după formula CMMMC(a,b)=a*b / CMMDC(a,b)
V. Șirul lui Fibonacci
1 1 2 3 5 8 13 21 34 55....................
a=1; b=1; cout<<a<<” “<<b<<” “; {Afișarea primilor n termeni din șir}
k=2;
do
{ c=a+b;
a=b;
b=c;
cout<<c<<“ “;
k=k+1;
}
while (k!=n);
Obs.: Instrucțiunile scrise italic se înlocuiesc, în funcție de problema de rezolvat
FIȘIERE

4
1. Declarare - pentru citire ifstream f(“date.in”);
- pentru scriere ofstream g(“date.out”);
2. Citire / scriere
f>>arg1>>...>>argn; g<<arg1<<...<<argn;
3. Închidere f.close(); g.close();
4. Funcții predefinite EoF(f)– verifică dacă s-a ajuns la sfârșitul fișierului
- se folosește construcția while(!f.eof())

VECTORI (TABLOURI UNIDIMENSIONALE)


1. Declarare int v[20]; - un vector care poate reține cel mult 20 valori numere întregi
2. Utilizare
- vectorul nu poate fi citit sau afișat ca variabilă, ci numai pe componente (elemente) de forma v[i]
- v[i] se referă la elementul de pe poziția i (v[i] = valoarea, iar i = poziția)
3. Parcurgere
for(i=0;i<n;i++)<prelucrare v[i]>
4. Elemente egal depărtate de capete (simetrice): v[i] v[n-i-1]
5. Operații
- parcurgere cu prelucrare perechi consecutive
for(i=0;i<n-1;i++)<prelucrare (v[i], v[i+1])>
- prelucrarea tuturor perechilor distincte din vector
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)<prelucrare (v[i], v[j])>
- prelucrarea tuturor perechilor din vector
for(i=0;i<n;i++)
for(j=0;j<n;j++) <prelucrare (v[i], v[j])>
- determinare maxim
max=-32000;
for(i=0;i<n;i++)
if (v[i]>max) max=v[i];
- căutarea unei valori x în vector
OK=0;
for(i=0;i<n;i++)
if (v[i]==x) OK=1;
- formulă construcție vector (adăugarea unei valori x în vector)
v[k]=x; sau v[k++]=x
k++;
- algoritmul de căutare binară a unei valori x, într-un vector ordonat
OK=0;
pi=0; pf=n-1;
while (pi<=pf && OK==0)
{
m=(pi+pf)/2;
if (v[m]==x)OK=1;
else
if (v[m]<x)pi=m+1;
else pf=m-1;
}
- eliminarea elementului de pe poziția p din vector
for(i=p;i<n-1;i++) v[i]=v[i+1];
n=n-1;
- inserarea unei valori x în poziția p în vector
for(i=n-1;i>=p;i--) v[i+1]=v[i];
v[p]=x;
5
n++;
- sortarea unui vector
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if (v[i]>v[j])
{
aux=v[i];
v[i]=v[j];
v[j]=aux;
}
- interclasarea a 2 vectori (2 vectori ordonați a și b=> al treilea vector ordonat (c) cu toate valorile din a și b)
i=0; j=0;k=0;
while ((i<m) && (j<n)) while (i<m)
if (a[i]<b[j]) {
{ c[k++]=a[i]; c[k++]=a[i];
i++; i++;
} }
else while (j<n)
{ c[k++]=b[j]; { c[k++]=b[j];
j++; j++;
} }
for(i=0;i<k;i++) cout<<c[i]<<” “;

MATRICI (TABLOURI BIDIMENSIONALE)


1. Declarare int a[20][20]; - o matrice care poate reține cel mult 20 x 20 valori numere întregi
2. Utilizare
- matricea nu poate fi citită sau afișată ca variabilă, ci numai pe componente (elemente) de forma a[i][j]
- a[i][j] se referă la elementul de pe linia i și coloana j
3. Citire matrice Amn
for(i=0;i<m;i++)
for(j=0;j<n;j++)cin>>a[i][j];
4. Afișare matrice
for(i=0;i<m;i++)
{ for(j=0;j<n;j++)cout<<a[i][j]<<” “;
cout<<endl;
}
5. Parcurgere Am n pe linii
for(i=0;i<m;i++)
for(j=0;j<n;j++)<prelucrare a[i][j]>
6. Parcurgere Am n pe coloane
for(j=0;j<n;j++)
for(i=0;i<m;i++)<prelucrare a[i][j]>
7. - elemente simetrice de pe aceeași linie (egal depărtate de capete): a[i][j] a[i][n-j-1]
- elemente simetrice de pe aceeași coloană (egal depărtate de capete): a[i][j] a[m-i-1][j]
- elemente simetrice față de diagonala principală: a[i][j] a[j][i]
- elemente simetrice față de diagonala secundară: a[i][j] a[n-j-1][n-i-1]
Obs: Dacă matricea are liniile și coloanele numerotate de la 1, în toate formulele se înlocuiește -1 cu +1
8. Operații
- parcurgerea unei linii x din matrice
for(j=0;j<n;j++)<prelucrare a[x][j]>
- parcurgerea unei coloane x din matrice
for(i=0;i<m;i++)<prelucrare a[i][x]>
- eliminarea liniei x din matrice
6
for(i=x;i<m;i++)
for(j=0;j<n;j++) a[i][j]=a[i+1][j];
m--;
- eliminarea coloanei x din matrice
for(i=0;i<m;i++)
for(j=x;j<n;j++) a[i][j]=a[i][j+1];
n--;
9. Matrici pătratice An j>i
- diagonala principală (elemente de forma a[i][i], condiția j==i)
- parcurgere triunghi superior j< i
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++) <prelucrare a[i][j]>
- parcurgere triunghi inferior
for(i=1;i<n;i++)
for(j=0;j<i;j++)<prelucrare a[i][j]>
- diagonala secundară (elemente de forma a[i][n-i-1], condiția j==n-i-1)
- parcurgere triunghi superior
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++) <prelucrare a[i][j]> j<n-i-1
- parcurgere triunghi inferior
for(i=1;i<n;i++) j>n-i-1
for(j=n-i;j<n;j++) do <prelucrare a[i][j]>

ȘIRURI DE CARACTERE
1. Declarare char s[200]; - poate memora cel mult 200 caractere;
2. Utilizare
- șirurile de caractere se pot citi sau afișa ca variabilă ( cin.getline(s, 200), cout<<s), dar pot fi utilizate și pe
componente (elemente): s[i] se referă la caracterul de pe poziția i (s[i] = caracterul, iar i = poziția);
3. Parcurgere for( i=0;i<strlen(s);i++) <prelucrare s[i]>
Obs: dacă ștergem caractere din șir, nu se va folosi varianta de mai sus, ci instrucțiunea while, ca mai jos
(secvența șterge vocalele dintr-o frază s):
i=0;
while (i<strlen(s))
if (strchr(“aeiou”,s[i]))strcpy(s+i,s+i+1);
else i++;
Funcții predefinite
a. strlen(s) –returnează numărul de caractere ale șirului s (lungimea sa)
b. strcpy(s,t) –copiază șirul de caractere t în șirul de caractere s
Obs: cu această funcție se poate efectua și ștergerea unor caractere dintr-un string; strcpy(s+i,s+i+1)
șterge caracterul de pe poziția i
c. strncpy(s,t,n) –copiază primele n caractere din șirul de caractere t în șirul de caractere s
d. strcat(s,t) – concatenează șirul de caractere t la sfârșitul șirului de caractere s
e. strncat(s,t,n) – concatenează primele n caractere din șirul de caractere t la sfârșitul șirului de caractere s
f. strchr(s,c) – caută caracterul c în șirul de caractere s și returnează șirul de caractere începând cu poziția
primei apariții a lui c sau valoarea 0 (NULL), dacă nu îl găsește pe c în s
g. strstr(s,t) – caută pe t în s și returnează șirul de caractere începând cu poziția primei apariții a lui t sau
valoarea 0, dacă nu îl găsește pe t în s
h. strcmp(s,t) – compară cele două șiruri de caractere din punct de vedere lexicografic (alfabetic) și
returnează: 0 – dacă s=t, <0 – dacă s<t, >0 – dacă s>t
i. strtok(s, sep) – extrage entitățile (cuvintele) dintr-un șir de caractere (frază) s, cu ajutorul unui set de
separatori (în general caracterul spațiu)
j. strlwr(s) – convertește literele mari ale lui s în litere mici
k. strupr(s) – convertește literele mici ale lui s în litere mari
7
l. strrev(s) – inversează un șir de caractere s
m. atoi(s) – convertește un șir de caractere s la un număr int
n. atol(s) – convertește un șir de caractere s la un număr long
o. ltoa(x, s,b) – convertește un un număr long, scris în baza b (de obicei b este 10), la un șir de caractere s
p. itoa(x, s,b) – convertește un un număr int, scris în baza b (de obicei b este 10), la un șir de caractere s
4. Prelucrare frază cuvânt cu cuvânt (când cuvintele sunt separate printr-un spațiu)
char s[100], *p;
cin.getline(s,100);
p=strtok(s," ");
while(p)
{
<prelucrare p>
p=strtok(NULL," ");
}
VECTORUL DE FRECVENȚĂ
- memorează frecvența de apariție a fiecărei valori dintr-un domeni de valori (vi..vf)
v[i]=j <=> valoarea i apare de j ori (frecvența de apariție a lui i este j)
- declarare: int (long) v[vf+1];
Exemplu: int v[100] – memorează frecvența de apariție a numerelor cu cel mult 2 cifre
- construcție:v[x]++ sau v[x]=v[x]+1 (mărim cu o unitate numărul de apariții ale lui x)
- afișare (valorificare)
o var 1: prelucrează o singură dată fiecare număr i
for (i=vi;i<=vf;i++)
if <condiție pt v[i]><prelucrare i>
o var 2: prelucreză fiecare număr i conform cu numărul de apariții ale sale (v[i])
for (i=vi;i<=vf;i++)
for (j=1;j<=v[i];j++)<prelucrare i>
- aplicație: Fișierul numere.txt conține pe prima linie cel mult 1000000000 numere naturale cu cel mult 4
cifre.
a. Afișați pe ecran, în ordine descrescătoare, numerele distincte de 3 cifre care apar în fișier.
b. Afișați pe ecran, în ordine crescătoare, toate numerele de 3 cifre care apar în fișier.
long v[1000];
/*1000- pt că mă interesează numerele de 3 cifre,
long – pt că fiecare număr poate să aibă cel mult 1000000000 apariții în fișier*/
int main()
{
ifstream f(“numere.txt”);
int i,x;
while (f>>x)
if ((x>=100) && (x<=999))v[x]++;
//a.
for (i=999;i>=100;i--)
if (v[i]>0) cout<<i<<” “;
//b.
for(i=100;i<=999;i++)
for(j=1;j<=v[i];j++) cout<<i<<” “;
}

ÎNREGISTRĂRI

8
1. Descriere: este un tip de date structurat care permite memorarea simultană într-o singură variabilă a mai
multor caracteristici (atribute, proprietăți) de diferite tipuri ale unei entități
2. Declarare
Exemplu: Se doreşte utilizarea unei variabile p, care să memoreze simultan numele, vârsta şi înălţimea unei
persoane:
struct persoana
{ char nume[30];
int varsta, inaltime;
} p;
Obs.: După declararea tipului persoana, fără a declara variabile, acestea se pot declara ulterior, astfel:
persoana p,q,;
3. Utilizare
-Construcţia necesară pentru utilizare este: variabilă.câmp, în cazul nostru p.nume reprezintă numele
persoanei p, p.varsta reprezintă vârsta persoanei p, iar p.inaltime reprezintă înălţimea acesteia.
-variabilele de acest tip se pot utiliza doar prin intermediul acestor construcţii (doar aşa se pot citi, afişa sau
utiliza în diverse instrucţiuni), cu excepţia cazului în care se face atribuirea între două variabile ale aceluiaşi
tip. În acest caz, dacă am declara persoana p1, p2;, am putea utiliza construcţia p1=p2, instrucţiune prin
care toate caracteristicile memorate în p1 se atribuie şi lui p2.
-În anumite situații vor exista construcții de genul structură în structură. În acest caz, vor exista expresii
de forma variabilă.câmp.câmp

SUBPROGRAME
1. Descriere: sunt unităţi de program cu aceeaşi structură ca şi a funcției main() (antet, zonă de declarări, corp),
utilizate pentru a calcula o anumită valoare (funcţiile cu tip) sau pentru a executa diverse acţiuni sau secvenţe
de program (funcțiile fără tip).
2. Structură
void nume_funcție(parametri_formali); int nume_funcție(parametri_formali)
{ {
<zonă de declarări> <zonă de declarări>
instrucțiune1; instrucțiune1;
…………… ……………
instrucțiunen; instrucțiunen;
} return expresie
}
3. Terminologie
Parametri formali: parametrii utilizați la descrierea (definirea) subprogramului
Parametri actuali (efectivi): parametrii utilizați la apelul subprogramului în programul principal
Parametri prin valoare: acei parametri care intră cu o valoare în subprogram și la ieșire își păstrează valoarea
de la intrare, chiar dacă valoarea lor se modifică în interiorul subprogramului
Parametri prin referință: acei parametri care intră cu o valoare în subprogram și la ieșire își păstrează
valoarea primită (modificată) în interiorul subprogramului (sunt precedați de & la declarare)
Variabile globale: variabile declarate în zona de declarări a programului (deasupra funcției main()), care pot
fi utilizate oriunde în cadrul programului sau al oricăror subprograme și care au ca valoare inițială valoarea
implicită a tipului declarat (variabilele numerice au valoare implicită 0)
Variabile locale: variabile declarate în zona de declarări a unui subprogram, care pot fi utilizate (sunt
vizibile) doar în cadrul subprogramului respectiv
4. Utilizare
Subprogramele se definesc (se descriu) deasupra funcției main() și se apelează astfel:
- Funcțiile fără tip se apelează ca și instrucțiunile, sub forma nume_funcție(listă_parametri_actuali)
- Funcțiile cu tip se pot apela (de regulă):
- într-o instrucțiune de atribuire, în partea dreaptă a acesteia (exemplu: x=sum(a,b))
- într-o condiție (exemplu: if (sum(a,b)==4)...)
- ca parametru al instrucțiunii de tipărire (exemplu: cout<<sum(a,b))
5. Exemplu de utilizare a subprogramelor
9
Se citesc 4 numere întregi cu cel mult 4 cifre a, b, c, d. Scrieți un program care determină cel mai mare
divizor comun al celor 4 numere.
a. Varianta cu funcție cu tip
int a, b, c, d,p,q,r; {variabile globale}
int cmmdc(int x, int y); {antet}
{
while (x!=y)
if (x>y) x=x-y;
else y=y-x;
return x; {funcția primește valoarea calculată}
}
int main()
{ cin>>a>>b>>c>>d;
p=cmmdc(a,b); {apelează funcția pentru primele două numere}
q=cmmdc(c,d); {apelează funcția pentru ultimele două numere}
r=cmmdc(p,q); {apelează funcția pentru rezultatele obținute}
cout<<r;
//sau, mai scurt: cout<<cmmdc(cmmdc(a,b),cmmdc(c,d))
}
b. Varianta cu funcție fără tip
int a,b,c,d,p,q,r; {variabile globale}
void cmmdc(int x, int y,int &z); {antet}
{
while (x!=y)
if (x>y) then x=x-y;
else y=y-x;
z=x;
}
int main()
{
cin>>a>>b>>c>>d;
cmmdc(a,b,p); {apelează pentru primele două numere}
cmmdc(c,d,q); {apelează pentru ultimele două numere}
cmmdc(p,q,r); {apelează pentru rezultatele obținute}
cout<<r;
}
RECURSIVITATE
1. Descriere: este un mecanism de implementare a unui subprogram, care presupune apeluri (referiri) la el însuși
(autoapeluri) în cadrul definiției sale. Se pot implementa funcții cu tip sau funcții fără tip
2. Observații
-Orice definiție de funcție recursivă cu tip trebuie să prevadă cel puțin o situație (ramură) de oprire (în care
funcția primește o valoare concretă) și cel puțin o situație de continuare (autoapel)
-Pentru funcțiile fără tip se prevede, în general, doar situația de continuare (autoapel)
3. Exemple:
a. Scrieți un subprogram recursiv care determină numărul de cifre impare ale unui număr natural n
int nrcif(long n); void nrcif(long n, int &p);
{ if (n==0)return 0; { if (n!=0)
else { if (n%2==1) p++;
if (n % 2==1)return 1+f(n/10); nrcif(n/10,p);
else return f(n/10); }
} } //se va apela nrcif(n, 0)
b. Scrieți un subprogram recursiv care determină suma valorilor pozitive dintr-un vector v cu n elemente
int suma(int n);
{
if (n==0) return 0;
else
if (v[n]>0)return v[n]+suma(n-1);
else return suma(n-1);
10
}
c. Scrieți un subprogram recursiv care verifică dacă un vector conține numai valori pare
int f(int n);
{
if (n==0)return 1;
else
if (v[n]%2==0)return 0;
else return f(n-1);
}
d. Scrieți un subprogram recursiv care afișează valorile de 2 cifre dintr-un vector v cu n elemente
void p(int n);
{
if (n>0)
{
if ((v[n]>=10) && (v[n]<-99))cout<<v[n]<<” “;
p(n-1);
}
}
BACKTRACKING
Metoda Backtracking se utilizează în rezolvarea problemelor care îndeplinesc simultan următoarele condiții:
- soluția poate fi pusă într-un vector (stivă) x=(x1, x2, ..., xn), cu x1A1, x2A2,..., xnAn,
- A1, A2, ..., An sunt mulțimi finite, iar elementele lor se află într-o relație de ordine bine stabilită; de multe ori
A1, A2, ..., An coincid (se lucrează pe o singură mulțime A)
Metoda Backtracking are la bază următorul principiu:
- soluția x1, x2, ..., xn se construiește pas cu pas
- dacă se constată că pentru o anumită valoare aleasă nu se poate ajunge la soluție, se renunță la acea valoare
și se reia construcția din punctul unde am rămas
Mecanismul Backtracking (varianta lungă)
- se alege primul element x1A1
- presupunând generate elementele x1, x2, ..., xk, cu x1A1, x2A2,..., xkAk, se alege primul element
disponibil xk+1Ak+1 (se urcă în stivă o poziție); apar două posibilități:
- nu s-a găsit un astfel de element (x k+1Ak+1), caz în care se consideră generate elementele x 1, x2, ..., xk-1
(se coboară în stivă o poziție) și căutarea se reia cu următorul element netestat (succesor) al mulțimii A k
- a fost găsit un astfel de element (x k+1Ak+1), caz în care se verifică validitatea elementului respectiv;
apar din nou două posibilități:
- este valid, caz în care se testează dacă s-a ajuns la soluție; apar din nou două posibilități:
- s-a ajuns la soluție, se tipărește soluția și se reia algoritmul considerând generate elementele
x1, x2, ..., xk-1, căutând un element xk+1Ak+1 rămas netestat (succesor)
- nu s-a ajuns la soluție, caz în care se consideră generate elementele x 1, x2, ..., xk, xk+1 și se
caută un prim element xk+2Ak+2 (se urcă în stivă o poziție)
- nu este valid, caz în care se reia algoritmul considerând generate elementele x 1, x2, ..., xk, iar
elementul xk+1 se caută printre elementele netestate ale Ak+1 (se caută succesor)
- algoritmul se termină când nu mai există niciun element x 1A1 netestat
Mecanismul Backtracking (varianta scurtă)
- dacă un element xk ales (încărcat pe stivă) este valid, se testează dacă s-a ajuns la soluție
- dacă DA, se scrie soluția și se caută succesor pentru x k
- dacă NU, se urcă în stivă o poziție și se încarcă primul element x k+1 din mulțime
- dacă un element xk nu este valid, se caută un succesor pentru el
- dacă nu mai există succesor pentru xk, se coboară o poziție în stivă și se caută succesor pentru x k-1

GRAFURI
GRAFURI NEORIENTATE
11
Graf: Se numește graf neorientat cu n noduri și m muchii, notat G=(X, U), o pereche de mulțimi, unde:
- X={1,2,3,…n} se numește mulțimea nodurilor
- U={(x,y)|x, yX} se numește mulțimea muchiilor (m perechi neordonate din X)
Noduri adiacente: două noduri între care există muchie
Gradul unui nod: numărul de muchii incidente nodului respectiv (care trec prin nod)
Nod izolat: un nod prin care nu trece nici o muchie
Obs: gradul maxim al unui nod este n-1
Teoremă: Într-un graf cu n noduri și m muchii suma gradelor nodurilor este de două ori numărul muchiilor
n

∑ d ( xi )=2∗m
i=1
Graf parțial: Un graf obținut prin eliminarea unor muchii
Subgraf: Un graf obținut prin eliminarea unor noduri, împreună cu muchiile incidente
Graf complet: Un graf în care oricare două noduri sunt adiacente (între oricare două noduri există muchie)
n∗(n−1)
Teoremă: Un graf complet cu n noduri are muchii
2
Lanț: O succesiune de noduri, cu proprietatea că între oricare două noduri succesive există muchie
Lanț elementar: Un lanț în care toate nodurile sunt distincte
Ciclu: Un lanț în care primul nod este egal cu ultimul și toate muchiile sunt distincte (nu se trece de două ori
prin aceeași muchie)
Ciclu elementar: Un ciclu în care toate nodurile sunt distincte, cu excepția primului și ultimului nod
Lungimea unui lanț (ciclu): Numărul de muchii care intră în componența acestuia
Graf conex: Un graf în care între oricare două noduri există un lanț (care le unește)
Componentă conexă: Un subgraf conex, maximal în raport cu proprietatea de conexitate (nu mai pot fi
adăugate noduri la subgraf, astfel încât acesta să rămână conex)
Obs: 1. Un nod izolat reprezintă o componentă conexă
2. Un graf este conex dacă are o singură componentă conexă
Ciclu hamiltonian: Un ciclu elementar care trece prin toate nodurile grafului
Ciclu eulerian: Un ciclu care trece prin toate muchiile grafului
Graf hamiltonian: Un graf care conține un ciclu hamiltonian
Graf eulerian: Un graf care conține un ciclu eulerian
Teoremă: Un graf este eulerian  este conex și toate nodurile au grad par
Obs: 1. Un graf complet este graf eulerian dacă are număr impar de noduri
2. Un graf complet este totdeauna graf hamiltonian
Reprezentarea grafurilor neorientate:
1. Matricea de adiacență – o matrice pătratică, simetrică față de diagonala principală, în care elementele a[i]
[j]=1, dacă există muchie între nodurile i și j, sau a[i][j]=0, dacă nu există muchie
2. Liste ale vecinilor – pentru fiecare nod se enumeră vecinii săi
Parcurgerea grafurilor neorientate:
1. Parcurgerea în lățime– se vizitează un prim nod, care se introduce în coadă, apoi se vizitează toți vecinii
nevizitați acestuia, apoi, în ordinea nodurilor introduse în coadă, se vizitează vecinii nevizitați ai acestora,
șamd
2. Parcurgerea în adâncime – se vizitează un prim nod, apoi primul vecin nevizitat al acestuia, apoi primul
vecin nevizitat al acestuia, șamd

GRAFURI ORIENTATE
Graf: Se numește graf orientat cu n noduri (vârfuri) și m arce, notat G=(X, U), o pereche de mulțimi, unde:
- X={1,2,3,…n} se numește mulțimea vârfurilor
- U={(x,y)|x, yX} se numește mulțimea arcelor (m perechi ordonate din X)
Pentru arcul (x, y): x este extremitatea inițială, iar y este extremitatea finală
Gradul exterior al unui nod x (d+(x)): numărul arcelor care au extremitate inițială pe x (numărul arcelor care
pornesc din x)
Gradul interior al unui nod x (d-(x)): numărul arcelor care au extremitate finală pe x (numărul arcelor care
ajung în x)
Teoremă: Într-un graf orientat cu n noduri și m arce, suma gradelor exterioare este egală cu suma gradelor
interioare și cu numărul de arce:

12
n n

∑ d+ ¿( x ) =∑ d−¿( x ) =m¿ ¿
i i

i=1 i=1
Graf complet: Un graf orientat în care oricare două noduri sunt adiacente (între oricare două noduri există cel
puțin un arc)
n∗(n−1)
Obs: 1. Numărul grafurilor orientate complete cu n noduri este 3 2

n∗(n−1)
2.Într-un graf complet cu n vârfuri, există între și n*(n-1) arce
2

Reprezentarea grafurilor orientate:


1. Matricea de adiacență – o matrice pătratică, în care elementele a[i][j] au valoarea 1, dacă există arc de la
nodul i la nodul j, sau 0, dacă nu există arc
2. Liste ale vecinilor – pentru fiecare nod x se enumeră vecinii săi y (pentru fiecare arc (x, y) )
Lanț: O succesiune de arce, cu proprietatea că oricare două arce vecine au o extremitate comună (un nod
comun)
Drum: O succesiune de noduri, cu proprietatea că între oricare două noduri succesive x și y există arcul (x,y)
Drum elementar: Un drum în care toate nodurile sunt distincte
Circuit: Un drum în care primul nod este egal cu ultimul și toate arcele sunt distincte
Circuit elementar: Un circuit în care toate nodurile sunt distincte, cu excepția primului și ultimului nod
Graf conex: Un graf în care între oricare două noduri există un lanț (care le unește)
Graf tare conex: Un graf în care între oricare două noduri există un drum (pentru orice două noduri x și y
există drum de la x la y și de la y la x)

ARBORI
Arbore: Se numește arbore un graf neorientat conex și fără cicluri
Teoremă: Un arbore cu n noduri are n-1 muchii
Obs: Un arbore se reprezintă pe nivele, pe nivelul cel mai de sus fiind nodul rădăcină
Descendent al unui nod x: Un nod y, situat pe un nivel inferior în lanțul care îl leagă de nodul x
Descendent direct = fiu
Fiu al unui nod x: Un nod y, situat pe nivelul imediat inferior, legat prin muchie de x
Acendent al unui nod x: Un nod y, situat pe un nivel superior în lanțul care îl leagă de nodul x
Ascendent direct = tată
Tatăl unui nod x:Un nod y, situat pe nivelul imediat superior, legat prin muchie de x
Rădăcină: Nodul de pe primul nivel, care nu are tată
Frunză (nod terminal): Un nod care nu are descendenți
Frate al unui nod x: un nod care are același tată ca și x
Obs: Gradul unei frunze este 1
Înălțimea unui arbore: Lungimea celui mai lung lanț elementar care leagă rădăcina de un nod al arborelui
Arbore binar: Un arbore în care fiecare nod are cel mult doi descendenți direcți (fii)
Arbore binar complet: Un arbore binar în care fiecare nod, cu excepția frunzelor, are exact doi descendenți
direcți (fii)
Reprezentarea arborilor oarecare:
1. Vectorul de tați (t): t[i]=0, dacă i este nodul rădăcină, sau t[i]=j, dacă j este tatăl lui i
2. Matricea de adiacență
3. Liste ale vecinilor

13

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