Tentamen Programmeermethoden 5 januari 2016 Uitwerkingen OPGAVE 1 a. bool hoe (int A[ ], int X, int n) { int i; for ( i = 0; i < n; i++ ) if ( A[i] - X <= 1 && X - A[i] <= 1 ) return true; return false; }//hoe b. int langste (int A[ ], int n, int & gem) { int leng = 1, i, delangste = 1, mijngem = A[0]; gem = A[0]; for ( i = 0; i < n-1; i++ ) if ( A[i] <= A[i+1] ) { leng++; mijngem += A[i+1]; if ( leng > delangste ) { delangste = leng; gem = mijngem; }//if }//if else { leng = 1; mijngem = A[i+1]; }//else gem = (int) ( (double) gem / delangste + 0.5 ); return delangste; }//langste c. void busort (int A[ ], int n) { int i, temp; bool klaar = false, even = true; while ( ! klaar ) { klaar = true; if ( even ) for ( i = 0; i < n-1; i++ ) if ( A[i] > A[i+1] ) { temp = A[i]; A[i] = A[i+1]; A[i+1] = temp; klaar = false; }//if else for ( i = n-2; i >= 0; i-- ) if ( A[i] > A[i+1] ) { temp = A[i]; A[i] = A[i+1]; A[i+1] = temp; klaar = false; }//if even = !even; }//while }//busort d. minimaal: 1 ronde, dus n-1 vergelijkingen; alleen voor een reeds (oplopend) gesorteerd rijtje maximaal: n rondes, met elk n-1 vergelijkingen; totaal n(n-1) stuks; bijvoorbeeld voor een omgekeerd gesorteerd rijtje OPGAVE 2 a. Globale variabelen gelden in het gehele programma, en worden helemaal bovenin aangemaakt. Locale variabelen gelden (tijdelijk) alleen in de functie waarin ze aangemaakt zijn. Variabelen kunnen call by value en call by reference worden meegegeven aan een functie. Bij call by value gaat alleen de waarde van de parameter naar de functie, alwaar een locale variabele deze waarde opvangt, en er met deze locale variabele wordt verder gerekend. De oorspronkelijk variabele behoudt zijn waarde. Bij call by reference (&) gaat als het ware de variabele zelf naar de functie, en kan dan ook blijvend veranderd worden. Eigenlijk wordt het adres (de reference) doorgegeven. Formeel: in functieheading, bijvoorbeeld x, y in int f (int x, bool y) { Actueel: bij aanroep, bijvoorbeeld r en y in z = f (r,y); b. 7,21,6 LF -8 LF 1,4 LF (LF is een regelovergang) c. 7,20,5 LF -8 LF 20,5 LF maar ook 7,19,5 LF -7 LF 19,5 LF De volgorde bij optellen ligt in C++ niet vast d. Dan moet er een prototype van donald boven hillary staan (anders kent hillary donald niet), en beide parameters van donald moeten call by value zijn (want 42 en a-a zijn geen l-values). e. 2(1-r-s) OPGAVE 3 a. int druk (int M[ ][n], int & som) { int i, j, kolom, desom; som = -1; for ( j = 0; j < n; j++ ) { desom = 0; for ( i = 0; i < m; i++ ) desom += M[i][j]; if ( desom >= som ) { som = desom; kolom = j; }//if }//for return kolom; }//druk b. int duos (int M[ ][n]) { int i, j, tel = 0; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) { if ( j+1 < n && ( M[i][j] == 2*M[i][j+1] || 2*M[i][j] == M[i][j+1] ) ) tel++; if ( i+1 < m && ( M[i][j] == 2*M[i+1][j] || 2*M[i][j] == M[i+1][j] ) ) tel++; }//for return tel; }//duos c. int aantal (int M[ ][n], int & i, int & j) { int stappen = 0, r, s; bool al[m][n]; for ( r = 0; r < m; r++ ) for ( s = 0; s < n; s++ ) al[r][s] = false; while ( ! al[i][j] ) { al[i][j] = true; if ( stappen % 2 == 0 ) j = ( j + M[i][j] ) % n; else i = ( i + M[i][j] ) % m; stappen++; }//while return stappen; }//aantal OPGAVE 4 Tegenwoordig gebruiken we nullptr in plaats van NULL. a. void voegtoe (kamer* & eerste, int kamernr, char kamernm) { kamer* nieuw = new kamer; nieuw->vorig = NULL; nieuw->volg = eerste; nieuw->nr = kamernr; nieuw->naam = kamernm; if ( eerste != NULL ) eerste->vorig = nieuw; eerste = nieuw; }//voegtoe b. void verwijder (kamer* & eerste) { kamer* weg = eerste; if ( eerste != NULL ) { eerste = eerste->volg; delete weg; if ( eerste != NULL ) { eerste->vorig = NULL; if ( eerste->volg != NULL ) eerste->volg->vorig = eerste; }//if }//if }//verwijder c. void wissel (kamer* eerste) { int temp; if ( eerste != NULL && eerste->volg != NULL && ( eerste->naam == eerste->volg->naam + ('a'-'A') || eerste->volg->naam == eerste->naam + ('a'-'A') ) ) { temp = eerste->nr; eerste->nr = eerste->volg->nr; eerste->volg->nr = temp; }//if }//wissel d. Als de ingangspointer niet verandert, bij c dus, hoeft het niet. Bij a en b moet het wel (overigens, bij b verandert eerste niet als hij toevallig NULL was). e. void herstel (kamer* eerste) { kamer* p = eerste; kamer* q = eerste; if ( eerste != NULL && eerste->volg != NULL ) { p = eerste->volg->volg; while ( p != NULL ) { p->vorig = q; p = p->volg; q = q->volg; }//while }//if }//herstel