

[vc_row][vc_column][vc_column_text]
O întrebare pe care o primim destul de des de la studenții noștri este cum abordăm noi, ca profesori, problemele date la concursuri. Intuiția vă spune că noi avem foarte multă experiență și ne bazăm strict pe ea. Este foarte adevărat că munca susținută ajută enorm, însă există mici trucuri de care ne folosim să grăbim procesul de rezolvare. Pentru studenți, acestea alcătuiesc o listă de sfaturi pentru olimpiadă. Și cum OSEPI, etapa națională este foarte aproape, s-ar putea să vă prindă bine să citiți.
Scopul principal al îndemnurilor noastre estă să câștigați timp prețios, atât la scrierea codului cât și la găsirea unei posibile erori. Veți observa că introducerea ordinii în procesul de scriere al codului vă va salva de la multe situații neplăcute.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Problemele de informatică, mai ales cele propuse în concursuri, vor avea enunțuri complexe, uneori foarte lungi. Sarcina voastră este să le deslușiți. Nu puteți programa până când nu înțelegeți ce a vrut autorul problemei de la voi.
Așa că, trageți aer în piept, înarmați-vă cu răbdare și citiți problema de câte ori este nevoie până când totul este clar. Adică până când puteți răspunde la următoarele întrebări corect:
Dacă aveți dubii la oricare dintre întrebările de mai sus, mai citiți o dată problema. Luați hârtie și pix și începeți să formulați algoritmul vostru folosind datele de intrare date ca exemplu. Verificați și iar verificați până când sunteți siguri că totul este clar. Abia atunci treceți la calculator să codați.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Nu mă refer la tehnica recursivă de programare, ci mai degrabă la concept și cum trebuie abordată problema pe care trebuie să o rezolvăm. După ce ați înțeles ce trebuie făcut, problema trebuie „spartă” în subprobleme clare și cu rezolvare directă.
Pentru o înțelegere mai bună, să luăm o problemă simplă, Cfdist. Problema poate fi împărțită în următoarele subprobleme:
Logic, nu e așa? 3 pași vor fi prezenți întotdeauna, indiferent de problemă. Aceștia sunt pașii 1, 2 și 5. Ceilalți pași sunt dependenți de problema în sine.
Tot la acest pas trebuie să vă gândiți la tehnica de lucru, la ce algoritmi folosiți ca să rezolvați mai eficient problema. Acești algoritmi vă vor indica subproblemele voastre. De exemplu, dacă problema presupune lucrul cu numere prime, cel mai probabil o subproblemă va fi precalcularea ciurului lui Eratostene.
Uneori, veți vedea că unii pași se continuă în alții. De aceea, este bine să folosiți comentarii și să înțelegeți ce vreți să faceți.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Comentariile reprezintă o unealtă importantă în procesul de programare. O mică frază înainte de fiecare subproblemă vă va ajuta să realizați cum este împărțit programul vostru.
Tot comentariile pot fi utile să lăsați scris un exemplu în dreptul unei comenzi. De ce? Pentru că de multe ori veți fi nevoiți să tratați un caz particular și veți uita de ce ați pus o comanda IF într-un anumit loc.
Ele devin și mai importante dacă programul vostru nu rulează corect și trebuie să faceți verificări. Puteți câștiga timp prin o navigare mai ușoară prin cod.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Suntem la un nivel destul de înalt. Problemele pe care trebuie să le rezolvați necesită multe variabile, mulți vectori și, uneori, multe matrici. Codul poate fi foarte lung. Dacă ne uităm la problemele OSEPI 2021, etapa județeană, aveați destul de mult de scris la ele.
Să luăm următoarea bucată de cod:
[/vc_column_text][vc_column_text]
fscanf( fin, "%d%d%d", &p, &r, &k );
for ( l = 0; l <= r+1; l++ )
per[l][0] = per[0][l] = per[l][r+1] = per[r+1][l] = B;
for ( i = 0; i < k; i++ ) {
fscanf( fin, "%d%d ", &l, &c );
tab[l][c] = fgetc( fin );
}
[/vc_column_text][vc_column_text]
Plecăm de la premiza că acest cod este corect, ca și logică. Este un cod destul de curat, pe care îl veți întâlni adesea. Dar cât de ușor este de înțeles la prima vedere? Mai ales dacă această secvență este scoasă din contextul programului principal. Dacă ar fi greșită, cât de ușor ar fi să ne dăm seama de ce se întâmplă?
Dar dacă l-am scrie astfel?
[/vc_column_text][vc_column_text]
fscanf( fin, "%d%d%d", &cerinta, &dimensiune_matrice, &casute_semnalizare );
for ( linie = 0; linie <= dimensiune_matrice+1; linie ++ )
perechi[l][0] = perechi[0][l] = perechi[l][dimensiune_matrice+1] = perechi[dimensiune_matrice+1][l] = BORDARE;
for ( pas = 0; pas < casute_semnalizare; pas++ ) {
fscanf( fin, "%d%d ", &linie, &coloana );
tabla[linie][coloana] = fgetc( fin );
}
[/vc_column_text][vc_column_text]
Deja schimbarea este evidentă. Putem identifica datele problemei mai ușor și pot urmări ce se întâmplă cu variabilele din program. Prin denumirea clară a lor, pot face verificări rapid în cod pentru depanare.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Înainte să scrieți mult la rezolvarea problemei, misiunea voastră este una scurtă și simplă: să fiți siguri că citiți datele de intrare corect. Trebuie să puteți să citiți fișierul de intrare corect și să îl afișați identic în fișierul de ieșire. Nu treceți mai departe la rezolvarea problemei dacă nu ați îndeplinit acest pas.
Dacă nu aveți datele de intrare corecte, problema va arunca doar rezultate greșite și veți pierde timp prețios căutând greșeala.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Este la fel ca așezarea în pagină a temei la limba română, când scriem o compunere. Programul are secțiuni clar definite. Comenzile imbricate trebuie să fie clare, la rândul lor. Această claritate se obține prin indentarea corectă.
Să studiem următoarea bucată de cod:
[/vc_column_text][vc_column_text]
for(i=1; i<=9; i+=2) while(v[i]>0){
b=b*10+i;
v[i]--;
}
for(i=8; i>=0; i-=2)
while(v[i]>0){
b=b*10+i;
v[i]--;
}
[/vc_column_text][vc_column_text]
Prima comandă FOR are pe aceeași linie comanda WHILE. Folosirea acoladelor lasă senzația că instrucțiunile aparțin comenzii FOR. Dacă nu suntem atenți, putem cădea în această capcană lejer.
A doua comandă FOR este scrisă puțin mai bine, în sensul în care comanda WHILE este pe rândul propriu următor. Însă în ambele structuri repetitive, lipsa indentării duce la o urmărire greoaie. Nici nu vreau să mă gândesc cum trebuie să verific codul în cazul de erori…
Iată o scriere lizibilă, indentată a codului anterior:
[/vc_column_text][vc_column_text]
for(i=1; i<=9; i+=2)
while(v[i]>0){
b=b*10+i;
v[i]--;
}
for(i=8; i>=0; i-=2)
while(v[i]>0){
b=b*10+i;
v[i]--;
}
[/vc_column_text][vc_column_text]
De remarcat:
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_empty_space height=”50px”]
Cel mai probabil nu veți putea rezolva problema perfect din prima. Va trebui să reveniți asupra codului, să identificați unde programul nu funcționează corect. Dacă ați respectat sfaturile de mai sus, atunci verificarea se poate face rapid, sau cum spun unii, chirurgical 🙂 .
Niciodată nu vom folosi debugger-ul. Sunt mai multe motive de ce insist să nu o faceți, însă iată 3 dintre ele care ar trebui să fie mai mult decât convingătoare:
Voi prezenta metodele pe care le folosesc eu, în peste 10 ani de experiență în programare.
[/vc_column_text][vc_column_text]
O metodă foarte utilă atunci când consola nu returnează mesajul „Process returned 0”. Înseamnă că programul s-a blocat undeva înainte de ultima linie din programul principal (main).
Vom comenta secțiuni din program, pornind de la sfârșit către început. Cu fiecare secțiune comentată, vom rula programul și vom urmări mesajul din consolă, până când primim mesajul corect, „Process returned 0”. Astfel, vom identifica până unde programul rulează corect.
Apoi, vom comenta de sus în jos, începând cu prima secțiune de sub locul identificat anterior. Vom merge în jos până când programul nu mai rulează corect. În acest fel, am izolat secțiunea defectă.
Prin secțiune, mă refer la părți de cod, pe care voi le apreciați. De exemplu, o structură repetitivă FOR sau WHILE. Dacă acestea au subordonate mai multe comenzi, pot comenta dintre comenzile subordonate.
Dacă problema se rezolvă cu fișiere, nu înseamnă că nu vom mai folosi consola. Consola va servi afișărilor intermediare, menite să ne ajute să descoperim greșeli. Ceea ce este afișat în consolă trebuie comparat cu rezultatele calculelor noastre, pe care le-am făcut independent de program (probabil pe hârtie, pentru că este cel mai rapid). Practic, ne construim propriul debugger, lucru posibil în orice limbaj de programare și în orice situație.
Afișările le vom face înainte și după testarea unor condiții. Acolo este cel mai important. Vedem ce valori aveau toate variabilele implicate în test sau înainte de test. Astfel, înțelegem cum am depășit condiția. Vom avea răspuns la următoarele întrebări:
Elucidarea acestor întrebări vor conduce cu siguranță la concluzia căutată: aici este sau nu greșeala? Dacă da, atunci, cum se produce ea?
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_separator][vc_column_text]
După cum ați putut citi, toate indicațiile de mai sus, aceste sfaturi pentru olimpiadă vă pot câștiga mult timp atunci când aveți de revizuit codul. Metodele de redactare ale codului și cele de depanare sunt universale, pentru orice limbaj de programare. Tot ce trebuie să faceți este să le aplicați pas cu pas.
Articol scris de către Mihai Tuțu.
[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column offset=”vc_hidden-sm vc_hidden-xs”][vc_cta h2=”Participă și tu la cursurile de informatică Nerdvana!” txt_align=”center” style=”flat” el_width=”xs” add_button=”bottom” btn_title=”Vezi calendarul cursurilor de informatică” btn_style=”flat” btn_color=”primary” btn_align=”center” btn_i_icon_fontawesome=”fas fa-pen” btn_add_icon=”true” btn_link=”url:https%3A%2F%2Fnerdvana.ro%2Fcursuri%2Fcursuri-informatica%2F|title:Cursuri%20Informatic%C4%83″]
Dacă vrei să înveți mai multe despre programare sau vrei să te pregătești de un concurs, plecând de la filosofia enunțată mai sus, înscrie-te la cursurile noastre!
[/vc_cta][/vc_column][/vc_row][vc_row][vc_column offset=”vc_hidden-lg vc_hidden-md”][vc_cta h2=”Participă și tu la cursurile de informatică Nerdvana!” txt_align=”center” style=”flat” add_button=”bottom” btn_title=”Vezi calendarul cursurilor de informatică” btn_style=”flat” btn_color=”primary” btn_size=”sm” btn_align=”center” btn_i_icon_fontawesome=”fas fa-pen” btn_add_icon=”true” btn_link=”url:https%3A%2F%2Fnerdvana.ro%2Fcursuri%2Fcursuri-informatica%2F|title:Cursuri%20Informatic%C4%83″]
Dacă vrei să înveți mai multe despre programare sau vrei să te pregătești de un concurs, plecând de la filosofia enunțată mai sus, înscrie-te la cursurile noastre!
[/vc_cta][/vc_column][/vc_row]