De ce avem nevoie de repetitie?
Imagineaza-ti ca vrei sa afisezi numerele de la 1 la 100. Ar fi obositor sa scrii 100 de instructiuni separate, una pentru fiecare numar! Structura FOR ne permite sa repetam instructiuni automat, de un numar cunoscut de ori. In loc de 100 de linii de cod, scriem doar 3 linii si calculatorul face restul.
In viata de zi cu zi intalnesti repetitia peste tot. Cand faci 10 genuflexiuni la sport, stii dinainte ca vei repeta miscarea de exact 10 ori. Cand profesorul spune "Copiati de 5 ori aceasta propozitie", stii numarul exact de repetitii. Cand numeri de la 1 la 20 in engleza, repeti acelasi tipar de 20 de ori. In toate aceste situatii, numarul de repetitii este cunoscut dinainte - exact tipul de situatie pentru care a fost creata structura FOR.
Repetitia este unul dintre cele trei concepte fundamentale din programare, alaturi de secventa (instructiunile se executa in ordine) si decizia (instructiunile se executa doar daca o conditie este adevarata). Fara repetitie, programele ar fi foarte lungi si greu de scris. Practic, orice program care prelucreaza mai multe date foloseste o forma de repetitie.
In informatica, repetitia se mai numeste si bucla (loop in engleza) sau ciclu . Structura FOR este cel mai simplu tip de bucla si este ideala cand stii exact de cate ori vrei sa repeti o actiune. Exista si alte tipuri de bucle (WHILE, REPEAT) pe care le vei invata mai tarziu, dar FOR este punctul de plecare perfect pentru intelegerea conceptului de repetitie.
Structura FOR in pseudocod
Forma generala a structurii FOR este scrisa in pseudocod astfel:
// instructiuni care se repeta
SFARSIT_PENTRU
Structura are trei componente esentiale.
Contorul
este o variabila care numara repetitiile - de obicei se numeste
i
,
j
sau
k
.
Valoarea de start
este numarul de la care incepe numararea, iar
valoarea de sfarsit
este numarul pana la care se numara. La fiecare repetitie, contorul creste automat cu 1.
Gandeste-te la contor ca la un numarator automat — exact cum numeri la saritura cu coarda: "1, 2, 3, ... 10, gata!". La fiecare saritura adaugi 1 la contor, si cand ajungi la 10 te opresti. La fel, contorul din FOR porneste de la valoarea de start, creste cu 1 la fiecare pas si se opreste automat cand depaseste valoarea de sfarsit.
Este important sa intelegi ca tot ce se afla intre
PENTRU
si
SFARSIT_PENTRU
se numeste
corpul buclei
. Aceste instructiuni se repeta de fiecare data cand contorul avanseaza cu o pozitie. Poti pune orice instructiuni in corpul buclei: afisari, calcule, citiri, sau chiar alte structuri de decizie (DACA-ATUNCI).
Un detaliu important: cand contorul depaseste valoarea de sfarsit, bucla se opreste automat si programul continua cu instructiunile de dupa
SFARSIT_PENTRU
. Nu trebuie sa opresti bucla manual - ea stie singura cand sa se termine. De exemplu, daca contorul merge de la 1 la 5, dupa ce executa pasul cu i=5, bucla se incheie.
Primul exemplu - Afisam numere
Sa vedem cel mai simplu exemplu: afisarea numerelor de la 1 la 5. In loc sa scriem cinci instructiuni SCRIE separate, folosim o singura bucla FOR:
SCRIE ( i )
SFARSIT_PENTRU
Rezultat:
Sa urmarim executia pas cu pas. La inceput, contorul i primeste valoarea 1. Se executa instructiunea SCRIE(i), deci se afiseaza 1. Apoi contorul creste la 2, se afiseaza 2. Procesul continua: i devine 3 (se afiseaza 3), apoi 4 (se afiseaza 4), si in final 5 (se afiseaza 5). Dupa aceasta, contorul ar trebui sa devina 6, dar 6 depaseste valoarea de sfarsit (5), deci bucla se opreste.
Observa cat de elegant este acest cod. In loc de cinci linii separate (SCRIE(1), SCRIE(2), SCRIE(3), SCRIE(4), SCRIE(5)), am scris doar trei linii. Daca am vrea sa afisam numerele de la 1 la 1000, tot trei linii am folosi - doar am schimba valoarea de sfarsit din 5 in 1000. Aceasta este puterea repetitiei!
Poti folosi orice nume pentru contor, nu doar
i
. De exemplu, poti scrie
PENTRU numar = 1, 5
sau
PENTRU k = 1, 5
. Totusi, traditia in programare este sa folosesti literele
i
,
j
si
k
pentru contori, deoarece sunt scurte si usor de citit. Litera
i
vine de la "index" sau "iterator".
Un exercitiu mental: daca scriem
PENTRU i = 3, 3 EXECUTA SCRIE(i)
, ce se intampla? Se afiseaza o singura data numarul 3, deoarece contorul incepe de la 3 si se opreste tot la 3 - deci o singura executie. Iar daca scriem
PENTRU i = 5, 3 EXECUTA
? Nu se executa deloc, deoarece valoarea de start (5) este deja mai mare decat valoarea de sfarsit (3) — aceasta regula este valabila cand pasul este implicit +1 (adica atunci cand nu specificam un pas in enunt). Vei vedea in Atomul 9 ca un pas negativ inverseaza aceasta logica.
Calculam numarul de repetitii
Pentru a afla de cate ori se executa o bucla FOR, folosim o formula simpla. Nu trebuie sa numeri pe degete - formula iti da raspunsul instant:
Numar repetitii = valoare_sfarsit - valoare_start + 1
(formula valabila cand pasul este 1; pentru pas diferit de 1 formula se ajusteaza — vezi Atomul 9)
Sa aplicam formula pe un exemplu concret:
PENTRU i = 3, 7 EXECUTA
. Numarul de repetitii este 7 - 3 + 1 =
5 repetitii
. Valorile pe care le ia contorul i sunt: 3, 4, 5, 6, 7. Putem verifica: sunt intr-adevar 5 valori.
De ce adunam 1 in formula? Pentru ca atat valoarea de start cat si cea de sfarsit sunt incluse. Daca numeri de la 3 la 7, ai numerele 3, 4, 5, 6, 7 - adica 5 numere, nu 4. Este o greseala frecventa sa uiti de "+1" si sa calculezi gresit numarul de repetitii. Gandeste-te asa: de la 1 la 1 ai o repetitie (1-1+1=1), nu zero.
Iata cateva exemple pentru a consolida intelegerea:
PENTRU i = 1, 10
face 10-1+1 = 10 repetitii.
PENTRU i = 5, 5
face 5-5+1 = 1 repetitie (se executa o singura data).
PENTRU i = 1, 100
face 100-1+1 = 100 de repetitii. Observa cat de usor este sa calculezi - aplici formula si ai rezultatul imediat.
Aceasta formula este extrem de utila la teste si examene, unde ti se poate cere sa determini de cate ori se executa o bucla fara sa o "rulezi" mental. De asemenea, cand scrii un algoritm si vrei sa stii cati pasi va face, formula iti raspunde instant. In programarea reala, numarul de repetitii determina cat de repede ruleaza un program - de aceea este important sa il cunosti.
Folosim FOR pentru calcule - Suma
Bucla FOR nu este doar pentru afisare - o putem folosi pentru a face calcule complexe. Unul dintre cele mai comune exemple este calculul sumei numerelor. Sa calculam suma 1+2+3+4:
PENTRU i = 1 , 4 EXECUTA
s = s + i // adunam i la suma
SFARSIT_PENTRU
SCRIE ( s ) // afiseaza 10
Traseul algoritmului pas cu pas:
Initial: s = 0
i=1: s = 0 + 1 = 1
i=2: s = 1 + 2 = 3
i=3: s = 3 + 3 = 6
i=4: s = 6 + 4 = 10
Observa ca am initializat variabila
s
cu 0
inainte
de bucla. Aceasta este o regula esentiala: variabila acumulator trebuie sa aiba o valoare de pornire inainte de a incepe sa adaugam la ea. Daca nu initializam
s
cu 0, ea ar avea o valoare nedefinita si rezultatul ar fi gresit.
De ce initializam cu 0 si nu cu alta valoare? Pentru ca 0 este elementul neutru la adunare : 0 + orice numar = acel numar. Astfel, la primul pas (i=1), s devine 0+1=1, ceea ce este corect. Daca am fi initializat cu 5, la final am fi obtinut 15 in loc de 10 - un rezultat gresit.
Acest tip de algoritm se numeste algoritm acumulator : la fiecare pas, acumulam (adunam) o valoare noua la rezultatul partial. Este ca si cum ai avea un porcusor de bani in care pui cate o moneda de fiecare data - la final, porcusorul contine suma tuturor monedelor. In viata reala, calculezi media la o materie exact asa: aduni nota 1, apoi nota 2, apoi nota 3, si tot asa, construind suma pas cu pas.
FOR pentru inmultire - Factorial
Pe langa suma, putem folosi bucla FOR pentru a calcula produsul mai multor numere. Cel mai cunoscut exemplu este factorialul : produsul tuturor numerelor de la 1 pana la n. De exemplu, 3! (factorial de 3) = 1 * 2 * 3 = 6. Sa vedem algoritmul:
PENTRU i = 1 , 3 EXECUTA
p = p * i // inmultim p cu i
SFARSIT_PENTRU
SCRIE ( p ) // afiseaza 6
Traseul algoritmului:
Initial: p = 1
i=1: p = 1 * 1 = 1
i=2: p = 1 * 2 = 2
i=3: p = 2 * 3 = 6
Observa o diferenta importanta fata de suma: produsul se initializeaza cu 1 , nu cu 0. De ce? Pentru ca 1 este elementul neutru la inmultire: 1 * orice numar = acel numar. Daca am initializa cu 0, la primul pas am obtine 0*1=0, iar produsul ar ramane 0 pentru totdeauna (0 inmultit cu orice da 0).
Factorialul creste foarte repede cu cat n este mai mare. De exemplu: 4! = 24, 5! = 120, 6! = 720, 7! = 5040, 10! = 3.628.800. Factorialul este folosit in matematica pentru a calcula numarul de permutari (in cate moduri diferite poti aranja n obiecte). De exemplu, in cate ordini pot intra 5 elevi pe usa? Raspunsul este 5! = 120 de ordini posibile.
Regula de aur pentru initializare: suma se initializeaza cu 0, produsul se initializeaza cu 1 . Aceasta este una dintre cele mai importante reguli pe care trebuie sa le retii. La teste, o greseala de initializare inseamna un rezultat complet gresit, chiar daca restul algoritmului este corect.
In viata de zi cu zi, produsul repetat apare des: daca vrei sa stii in cate moduri diferite pot sta 5 prieteni la o masa, inmultesti 5*4*3*2*1 = 120 — exact ce face factorialul. Sau daca ai un cub Rubik cu 6 fete si vrei sa numeri toate combinatiile posibile, folosesti produse repetate. Aceleasi calcule stau la baza multor jocuri si aplicatii pe care le folosesti zilnic.
Reguli importante si greseli frecvente
Inainte de a avansa, sa consolidam regulile esentiale si sa identificam cele mai frecvente greseli pe care le fac elevii cand lucreaza cu structura FOR. Cunoasterea acestor capcane te va ajuta sa le eviti.
Regula 1 - Initializarea corecta:
- Pentru suma : initializeaza cu 0 (elementul neutru la adunare)
- Pentru produs : initializeaza cu 1 (elementul neutru la inmultire)
- Initializarea se face inainte de bucla, nu in interiorul ei
Regula 2 - Nu modifica contorul in interiorul buclei:
Contorul se modifica automat la fiecare pas. Daca il schimbi manual in corpul buclei (de exemplu, scrii
i = i + 2
in interiorul buclei), comportamentul devine imprevizibil si algoritmul va da rezultate gresite.
Greseala frecventa 1:
Initializarea variabilei acumulator in interiorul buclei. Daca scrii
s = 0
in corpul buclei, suma se reseteaza la fiecare pas si la final vei avea doar ultima valoare adunata, nu suma totala. Initializarea trebuie sa fie
o singura data
, inainte de FOR.
Greseala frecventa 2:
Confundarea valorii contorului cu numarul de repetitii. De exemplu,
PENTRU i = 5, 8
se executa de 4 ori (nu de 5 si nici de 8 ori). Foloseste intotdeauna formula: sfarsit - start + 1.
⚠️ Retine: Initializarea gresita = Rezultat gresit, chiar daca restul algoritmului e perfect!
Expresii cu contorul
Contorul
i
nu trebuie folosit doar direct - putem folosi
expresii matematice
cu el pentru a genera diferite secvente de numere. Aceasta tehnica este foarte puternica si ne permite sa cream tipare variate.
PENTRU i = 1 , 5 EXECUTA
SCRIE ( i * i )
SFARSIT_PENTRU
Rezultat: 1, 4, 9, 16, 25
i=1: 1*1=1 | i=2: 2*2=4 | i=3: 3*3=9 | i=4: 4*4=16 | i=5: 5*5=25
Prin expresii cu contorul putem genera orice secventa de numere dorim. De exemplu,
SCRIE(i*2)
afiseaza numerele pare: 2, 4, 6, 8, 10. Expresia
SCRIE(i*2-1)
afiseaza numerele impare: 1, 3, 5, 7, 9. Expresia
SCRIE(i*10)
afiseaza multiplii de 10: 10, 20, 30, 40, 50.
Un exemplu practic: tabla inmultirii cu un numar dat. Daca vrem sa afisam tabla inmultirii cu 7, scriem
PENTRU i = 1, 10 EXECUTA SCRIE("7 x ", i, " = ", 7*i)
. Rezultatul va fi: 7x1=7, 7x2=14, 7x3=21, si asa mai departe pana la 7x10=70. Este acelasi lucru pe care il faci cand inveti tabla inmultirii, dar calculatorul o face instantaneu!
Sa facem un traseu complet pentru
SCRIE(i*3+1)
cu i de la 1 la 4: i=1 afiseaza 1*3+1=4, i=2 afiseaza 2*3+1=7, i=3 afiseaza 3*3+1=10, i=4 afiseaza 4*3+1=13. Secventa obtinuta este 4, 7, 10, 13 - o progresie aritmetica cu ratia 3 (fiecare termen este cu 3 mai mare decat precedentul).
Aceasta capacitate de a genera secvente prin expresii matematice este fundamentala in programare. Multe probleme reale se reduc la a gasi expresia corecta care leaga contorul de valoarea pe care o vrem. De exemplu, pentru a genera secventa 100, 95, 90, 85, 80 folosim expresia
105 - i*5
cu i de la 1 la 5.
FOR cu pas diferit
Pana acum ai exersat sintaxa de baza a FOR cu contorul crescand 1 cate 1 (atomii 2-7). Acum extindem aceasta cunostinta cu o singura variatie: putem specifica cu cat sa creasca (sau sa scada) contorul la fiecare pas. Daca ai inteles ca FOR numara de la start la sfarsit pas cu pas, aceasta extindere este naturala — schimbam doar marimea pasului.
Pana acum, contorul a crescut cu 1 la fiecare pas. Dar putem schimba acest lucru folosind un pas (step) diferit. Pasul indica cu cat se modifica contorul dupa fiecare repetitie:
PENTRU i = 5 , 1 , -1 EXECUTA
SCRIE ( i )
SFARSIT_PENTRU
// Afiseaza: 5, 4, 3, 2, 1
In exemplul de mai sus, pasul este -1 , ceea ce inseamna ca la fiecare repetitie contorul scade cu 1. Contorul incepe de la 5 si merge in jos: 5, 4, 3, 2, 1. Cand ar ajunge la 0, bucla se opreste deoarece 0 este mai mic decat valoarea de sfarsit (1). Aceasta tehnica se numeste numarare inversa sau parcurgere descrescatoare .
PENTRU i = 2 , 10 , 2 EXECUTA
SCRIE ( i )
SFARSIT_PENTRU
// Afiseaza: 2, 4, 6, 8, 10
Aici pasul este 2 , deci contorul sare din 2 in 2: 2, 4, 6, 8, 10. Aceasta este o metoda eleganta de a genera doar numerele pare fara a folosi o conditie DACA. La fel, cu pasul 3 am genera: 3, 6, 9, 12 (multiplii de 3).
Numararea inversa (countdown) este folosita in multe situatii din viata reala: lansarea unei rachete ("5, 4, 3, 2, 1, LANSARE!"), cronometrul de la un examen care numara invers secundele ramase, sau un lift care afiseaza etajele in ordine descrescatoare cand coboara. In algoritmi, parcurgerea inversa este esentiala cand vrem sa procesam elementele unui sir de la sfarsit spre inceput.
Retine sintaxa: cand pasul este diferit de 1, il scriem ca al treilea parametru dupa valoarea de sfarsit. Daca pasul lipseste, se considera automat 1. Pasul poate fi orice numar intreg pozitiv sau negativ, dar nu poate fi 0 (ar crea o bucla infinita, deoarece contorul nu s-ar schimba niciodata).
FOR cu conditii (DACA in interiorul FOR)
Una dintre cele mai puternice tehnici este combinarea buclei FOR cu structura de decizie DACA-ATUNCI . Aceasta ne permite sa procesam selectiv doar anumite valori din cele generate de contor. De exemplu, putem numara cate numere pare exista intr-un interval:
PENTRU i = 1 , 10 EXECUTA
DACA i MOD 2 = 0 ATUNCI
c = c + 1
SFARSIT_DACA
SFARSIT_PENTRU
SCRIE ( c ) // afiseaza 5
Traseu: verificam fiecare numar de la 1 la 10
i=1: 1 MOD 2=1 (impar, NU numaram)
i=2: 2 MOD 2=0 (par, c=1)
i=3: 3 MOD 2=1 (impar, NU)
i=4: 4 MOD 2=0 (par, c=2)
... si asa mai departe ...
i=10: 10 MOD 2=0 (par, c=5)
Rezultat: c = 5 (sunt 5 numere pare: 2, 4, 6, 8, 10)
Operatorul
MOD
calculeaza restul impartirii. Daca restul impartirii unui numar la 2 este 0, numarul este par. Aceasta este cea mai folosita metoda de a verifica paritatea unui numar. La fel,
i MOD 3 = 0
verifica daca un numar este multiplu de 3.
Combinatia FOR + DACA este extrem de versatila. Poti numara cate numere dintr-un interval indeplinesc o conditie, poti calcula suma doar a anumitor numere, sau poti afisa selectiv doar valorile care te intereseaza. De exemplu, pentru a afisa doar numerele din intervalul 1-20 care sunt divizibile cu 3, scrii:
DACA i MOD 3 = 0 ATUNCI SCRIE(i)
.
Aceasta tehnica pregateste terenul pentru lucrul cu siruri (pe care le vei invata in lectia urmatoare), unde vei parcurge un sir de numere si vei procesa selectiv doar anumite elemente: cele pare, cele negative, cele mai mari decat o valoare data, sau cele care indeplinesc orice alta conditie definita de tine.
Un alt exemplu practic: sa aflam suma numerelor impare de la 1 la n. Combinam un acumulator (suma) cu o conditie de filtrare (numar impar):
s=0; PENTRU i=1,n EXECUTA DACA i MOD 2=1 ATUNCI s=s+i
. Pentru n=7, suma numerelor impare (1+3+5+7) este 16.
Iata traseul complet pentru acest exemplu: Initial s=0. La i=1: 1 MOD 2=1 (impar), deci s=0+1=1. La i=2: 2 MOD 2=0 (par), nu adunam. La i=3: 3 MOD 2=1 (impar), deci s=1+3=4. La i=4: par, nu adunam. La i=5: impar, s=4+5=9. La i=6: par, nu adunam. La i=7: impar, s=9+7=16. Rezultat final: s=16 . Aceasta combinatie FOR + DACA va fi folosita intensiv in lectiile urmatoare cand vom lucra cu siruri de numere.
Exercitii practice
Exercitiul 1 (Nivel minim) - Analizeaza algoritmi
Pentru fiecare algoritm de mai jos, determina ce valoare se afiseaza la final. Scrie traseul complet (valoarea variabilelor la fiecare pas) pentru a justifica raspunsul.
- PENTRU i=2,6 EXECUTA scrie(i*2) - Ce valori se afiseaza?
- s=0; PENTRU i=1,5 EXECUTA s=s+i - Ce valoare are s la final?
- PENTRU i=10,12 EXECUTA scrie(i) - Cate numere se afiseaza si care sunt?
- p=1; PENTRU i=1,4 EXECUTA p=p*i - Ce valoare are p la final? Ce calcul matematic reprezinta?
Raspunde numerotat: 1. ... 2. ... 3. ... 4. ...
Sfat: pentru fiecare exercitiu, fa un tabel cu coloanele "i" si "variabila" si completeaza-l pas cu pas. Aceasta tehnica se numeste "traseu de algoritm" si te ajuta sa nu gresesti.
Exercitiul 2 (Nivel standard) - Mini-proiect: Tabla inmultirii
Scrie in pseudocod un algoritm care citeste un numar n de la tastatura si afiseaza tabla inmultirii cu acel numar (de la n x 1 pana la n x 10). Algoritmul trebuie sa afiseze rezultatele in formatul "n x i = rezultat".
Cerinte obligatorii:
⭐ Bonus (pentru nota maxima):
- Adauga validarea datelor: verifica daca n este intre 1 si 10
- Calculeaza si afiseaza produsul tuturor rezultatelor (1*n * 2*n * ... * 10*n)
- Afiseaza cate rezultate din tabla inmultirii sunt numere pare
Scrie algoritmul pe caiet sau intr-un document, apoi verifica-l facand traseul pentru n=5.
Exercitiul 3 (Nivel performanta) - Analiza comparativa si proiectare
Cerinta: Ai la dispozitie doua probleme rezolvate cu FOR. Analizeaza-le, identifica ce diferentiaza solutiile lor si propune o imbunatatire pentru fiecare.
CITESTE(n)
s = 0
PENTRU i = 1, n EXECUTA
s = s + (2*i - 1)
SFARSIT_PENTRU
SCRIE(s)
CITESTE(n)
p = 0
PENTRU i = 1, n EXECUTA
p = p * i
SFARSIT_PENTRU
SCRIE(p)
Raspunde la urmatoarele puncte:
- Calculeaza ce afiseaza Algoritmul A pentru n=4. Arata traseul complet (valoarea lui s la fiecare pas).
- Algoritmul B contine o greseala de initializare. Identific-o si corecteaz-o. Ce valoare va produce Algoritmul B (cu greseala) pentru n=3? Ce ar trebui sa produca dupa corectare?
- Explica in 3-4 propozitii de ce initializarea difera intre algoritmul A (care calculeaza o suma) si algoritmul B (care calculeaza un produs). Foloseste notiunile de "element neutru".
Format: Raspunde numerotat (1, 2, 3) pe caiet. La punctul 1 scrie tabelul de traseu cu coloanele i / valoare_expresie / s. La punctele 2 si 3 scrie in propozitii complete.
Recapitulare: Structura FOR pe scurt
Sintaxa: PENTRU contor = start, sfarsit, pas EXECUTA ... SFARSIT_PENTRU
Nr. repetitii: sfarsit - start + 1 (cand pasul = 1)
Initializare suma: s = 0 (inainte de FOR)
Initializare produs: p = 1 (inainte de FOR)
Pas implicit: 1 (daca nu e specificat)
Pas negativ: contorul scade (parcurgere inversa)
FOR + DACA: procesare selectiva a valorilor
Expresii cu i: i*2 (pare), i*i (patrate), i*k (tabla inmultirii)