Biblioteca
Tutora
BibliotecaInformatică și TIC › clasa a VIII-a

Algoritmi și structuri de date

Elevii aprofundează conceptele de algoritm, structuri de date și metode de rezolvare a problemelor.

Evaluarea Națională

Algoritmul și proprietățile lui

Un algoritm este o succesiune finită și ordonată de pași prin care, pornind de la date de intrare, obținem date de ieșire — adică rezultatul problemei. Nu orice listă de pași e algoritm: trebuie respectate proprietățile algoritmilor, care se cer exact așa la evaluare:

Confuzia clasică: elevii cred că „algoritmul e programul”. Nu — algoritmul este ideea de rezolvare, iar programul este algoritmul scris într-un limbaj de programare. Același algoritm poate fi scris în pseudocod, în C++ sau în Pascal.

Algoritmii se reprezintă prin pseudocod (limbaj apropiat de cel natural, cu cuvinte-cheie ca „citește”, „scrie”, „dacă... atunci”, „cât timp”) sau prin schemă logică (desen cu blocuri: paralelogram pentru citire/scriere, dreptunghi pentru atribuiri, romb pentru decizii).

Tablouri unidimensionale (vectori)

Când avem multe valori de același tip (notele unei clase, temperaturile unei luni), nu declarăm 30 de variabile separate — folosim un tablou unidimensional, numit și vector: o înșiruire de elemente de același tip, așezate una după alta în memorie și accesate printr-un indice.

În pseudocod scriem v[1], v[2], ..., v[n]. În C++ declarăm int v[100]; și indicii pornesc de la 0, nu de la 1 — sursa clasică de greșeli când treci din pseudocod în cod.

Operațiile fundamentale, care apar în aproape orice subiect:

Regula de aur: indicele trebuie să rămână mereu în interiorul limitelor tabloului; accesarea lui v[n+1] este o eroare, chiar dacă uneori programul pare că merge.

Tablouri bidimensionale (matrice)

O matrice este un tablou cu două dimensiuni — un tabel cu linii și coloane. Elementul de pe linia i și coloana j se notează a[i][j]. Gândește-te la o tablă de șah: fiecare pătrățel e identificat de linia și coloana lui.

Parcurgerea pe linii folosește două bucle imbricate: pentru fiecare linie i, parcurgem toate coloanele j. Dacă inversăm buclele (j exterior, i interior), parcurgem pe coloane. Ordinea buclelor schimbă ordinea vizitării — întrebare tipică de urmărire a execuției.

La matricea pătratică (același număr de linii și coloane, n×n) apar noțiuni cerute des:

Greșeala clasică e confundarea celor două diagonale sau scrierea condiției diagonalei secundare cu indexarea greșită. Verifică mereu de unde pornesc indicii în enunț!

Prelucrări uzuale: suma elementelor de pe o linie dată, maximul de pe fiecare coloană, numărarea elementelor pare din matrice — toate sunt combinații de bucle imbricate cu operațiile învățate la vectori.

Subprograme: proceduri și funcții

Când o bucată de cod se repetă sau rezolvă o sarcină bine delimitată, o izolăm într-un subprogram. Avantajele: codul devine mai scurt, mai ușor de citit și de corectat — principiul modularizării.

Două tipuri de subprograme:

Vocabular care se punctează exact:

Parametrii formali și cei efectivi trebuie să corespundă ca număr, ordine și tip.

Confuzia frecventă: elevii cred că modificarea unui parametru transmis prin valoare schimbă și variabila de la apel. Nu! Prin valoare se lucrează pe o copie — originalul rămâne neschimbat.

Recursivitate – primii pași

Un subprogram este recursiv dacă se apelează pe el însuși. Pare magie, dar e doar o altă formă de repetiție: în loc de buclă, problema mare se reduce la o problemă mai mică de același fel.

Orice recursivitate corectă are OBLIGATORIU două părți:

Exemplul clasic, factorialul: n! = 1 · 2 · ... · n.

În C++: int fact(int n) { if (n == 0) return 1; return n * fact(n - 1); }

Cum se execută fact(3)? Se „desface” în 3 · fact(2), apoi 2 · fact(1), apoi 1 · fact(0), care returnează 1; abia apoi rezultatele se înmulțesc la întoarcere: 1, 1, 2, 6. Urmărirea acestor apeluri în ambele sensuri (coborâre și întoarcere) e exact ce se cere la exerciții.

Greșeala fatală: lipsa cazului de bază sau un caz de bază care nu e atins niciodată — apelurile nu se mai opresc și programul se blochează (depășire de stivă). Dacă fact ar fi apelat cu n negativ, condiția n == 0 nu s-ar îndeplini niciodată.

Eficiența algoritmilor

Două programe pot da același rezultat corect, dar unul termină într-o secundă și celălalt în ore. Eficiența unui algoritm măsoară cât de bine folosește resursele: timpul de execuție (numărul de operații efectuate) și memoria ocupată.

La nivelul clasei a VIII-a comparăm algoritmii prin numărul aproximativ de pași în funcție de n (dimensiunea datelor):

Exemplu concret: verificarea dacă un număr n este prim. Varianta naivă testează toți divizorii de la 2 la n−1. Varianta eficientă se oprește la radical din n, pentru că dacă n are un divizor mai mare decât radicalul, are obligatoriu și unul mai mic. Ambele sunt corecte; a doua e vizibil mai rapidă la numere mari.

De reținut: eficiența NU înseamnă cod mai scurt. Un program de trei rânduri poate fi mai lent decât unul de zece. Contează câte operații execută, nu câte rânduri are. La subiecte, când ți se cere un algoritm „eficient”, se așteaptă evitarea calculelor inutile — de exemplu să nu parcurgi vectorul de mai multe ori când ajunge o singură trecere.

De reținut

algoritm
succesiune finită și ordonată de pași care transformă datele de intrare în date de ieșire, rezolvând o clasă de probleme
finitudine
proprietatea algoritmului de a se încheia după un număr finit de pași, pentru orice date de intrare valide
generalitate
proprietatea algoritmului de a rezolva toate problemele dintr-o clasă, nu doar un caz particular
vector (tablou unidimensional)
structură de date formată din elemente de același tip, așezate succesiv în memorie și accesate prin indice
matrice (tablou bidimensional)
tablou organizat pe linii și coloane, în care elementul a[i][j] se află pe linia i și coloana j
diagonala principală
elementele unei matrice pătratice pentru care indicele de linie este egal cu indicele de coloană (i = j)
parametri formali
parametrii din definiția (antetul) unui subprogram, care primesc valori la apel
parametri efectivi
valorile sau variabilele concrete transmise subprogramului în momentul apelului
recursivitate
tehnica prin care un subprogram se apelează pe el însuși, având obligatoriu un caz de bază care oprește apelurile
caz de bază
situația simplă dintr-un subprogram recursiv în care rezultatul se returnează direct, fără un nou apel recursiv

Greșeli frecvente

Greșit: Inițializarea maximului cu 0 la determinarea maximului dintr-un vector
Corect: Maximul se inițializează cu primul element al vectorului; dacă toate elementele sunt negative, pornirea de la 0 dă un rezultat greșit
Greșit: Confundarea diagonalei principale cu cea secundară la matrice pătratice
Corect: Diagonala principală: i = j; diagonala secundară: i + j = n + 1 la indexare de la 1 (sau i + j = n − 1 la indexare de la 0)
Greșit: Uitarea inițializării sumei sau a contorului înainte de buclă
Corect: Variabilele acumulator (s = 0, contor = 0) se inițializează obligatoriu înaintea buclei, altfel pornesc de la o valoare imprevizibilă
Greșit: Subprogram recursiv fără caz de bază sau cu un caz de bază care nu e atins
Corect: Orice recursivitate corectă are un caz de bază care oprește apelurile și un caz general care se apropie sigur de el
Greșit: Credința că modificarea unui parametru transmis prin valoare schimbă variabila de la apel
Corect: Transmiterea prin valoare lucrează pe o copie; variabila originală de la apel rămâne neschimbată

Test — 6 întrebări ca la examen

1. Care proprietate a algoritmilor este încălcată de un program care intră într-o buclă infinită?
  1. generalitatea
  2. claritatea
  3. finitudinea
  4. corectitudinea datelor de intrare
Vezi răspunsul
finitudinea. Finitudinea cere ca algoritmul să se termine după un număr finit de pași — o buclă infinită încalcă exact asta. Claritatea, distractorul tentant, se referă la pași preciși, fără ambiguități, nu la oprirea execuției.
2. Într-un vector v cu n = 5 elemente, indexat de la 1: v = (3, 8, 8, 1, 6). Ce afișează algoritmul care numără elementele strict mai mari decât 5?
  1. 2
  2. 3
  3. 4
  4. 22
Vezi răspunsul
3. Elementele strict mai mari decât 5 sunt 8, 8 și 6 — deci contorul ajunge la 3. Varianta 2 apare dacă numeri cele două valori distincte (8 și 6) în loc de aparițiile lor; 22 este suma acestor elemente, nu numărul lor.
3. Într-o matrice pătratică a cu 4 linii și 4 coloane, indexată de la 1, elementul a[1][3] se află:
  1. pe diagonala principală
  2. pe diagonala secundară
  3. deasupra diagonalei principale
  4. sub diagonala principală
Vezi răspunsul
deasupra diagonalei principale. Pentru a[1][3] avem i = 1 și j = 3, deci i < j — element aflat deasupra diagonalei principale. Nu este pe diagonala secundară — distractorul tentant — pentru că aceasta cere i + j = n + 1 = 5, iar aici i + j = 4; și nici pe cea principală, unde ar trebui i = j.
4. Un subprogram C++ are antetul int f(int a, int b). La apelul s = f(x, 7), parametrii efectivi sunt:
  1. a și b
  2. x și 7
  3. s și f
  4. int și int
Vezi răspunsul
x și 7. Parametrii efectivi sunt valorile transmise la apel: x și 7. Variabilele a și b — distractorul clasic — sunt parametrii formali, cei din definiția subprogramului, care doar primesc valorile efective.
5. Se consideră funcția recursivă: int f(int n) { if (n == 0) return 0; return n + f(n - 1); }. Ce valoare returnează f(4)?
  1. 4
  2. 24
  3. 10
  4. 0
Vezi răspunsul
10. f(4) = 4 + f(3) = 4 + 3 + 2 + 1 + 0 = 10 — funcția calculează suma primelor n numere naturale. Varianta 24 e capcana: aceea ar fi factorialul (înmulțire), dar aici operația din cazul general este adunarea.
6. Pentru a verifica eficient dacă un număr natural n > 1 este prim, este suficient să căutăm divizori:
  1. de la 2 până la n − 1
  2. de la 2 până la n / 2
  3. de la 2 până la radical din n
  4. doar printre numerele impare mai mici decât n
Vezi răspunsul
de la 2 până la radical din n. Dacă n are un divizor mai mare decât radicalul său, atunci are obligatoriu și unul mai mic decât radicalul, deci verificarea până la radical din n este suficientă și mult mai rapidă. Varianta cu n/2 e corectă ca rezultat, dar nu e cea EFICIENTĂ cerută; iar ultima variantă ratează divizorul 2.
Deschide varianta interactivă — cu AI care îți explică
← Prezentări digitale și documente electroniceLimbajul de programare Pascal sau C++ →
BiologieChimieEconomieFilosofieFizicăGeografieInformatică și TICIstorieLogică și argumentareMatematicăPsihologieLimba și literatura română