Uitwerking tentamen Programmeermethoden 25 maart 2021 OPGAVE 1 a. bool pos (int A[ ], int n) { int i; for ( i = 0; i < n; i++ ) if ( A[i] < 0 ) return false; return true; }//pos b. int tel (int A[ ], int n, int v) { int i, teller = 0; for ( i = 0; i < n; i++ ) if ( A[i] < v ) teller++; return teller; }//tel c. void sorteer (int A[ ], int n) { int i = 0, teller, temp; while ( i < n ) { // of i < n-1 teller = tel (A,n,A[i]); if ( teller == i ) i++; // A[i] staat goed else { temp = A[i]; A[i] = A[teller]; A[teller] = temp; }//else }//while }//sort d. Stel het rijtje is 5 5 5 1 (n=4). Het eerste getal, de eerste 5, wordt dan (teller = 1) met de tweede 5 gewisseld. En zo blijft dat maar doorgaan. e. De functie van b doet altijd n vergelijkingen tussen array-elementen. Als het rijtje al goed stond (oplopend gesorteerd was), kost het n vergelijkingen per array-element. In totaal dus n*n = n^2. Dat is minimaal. Nu maximaal. Bijvoorbeeld (met n=10): 10 1 2 3 4 5 6 7 8 9. Eerst wordt 10 met 9 gewisseld, dan 9 met 8, enzovoorts. Na (algemener) (n-1)*n vergelijkingen hebben we 1 2 3 4 5 6 7 8 9 10, maar staan we nog vooraan. Dus alsnog n*n vergelijkingen, voor een totaal van n*(2n-1). 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. 4,2,9 LF 4,2,9 LF 4,2,9 LF 4,3,5 LF 27,3,5 LF (LF is LineFeed) c. De return-value blijft hetzelfde. Bij het afdrukken worden de twee eerste getallen nooit omgedraaid. Verder niks. d. 4,2,9 LF 3,1,7 LF 2,0,5 LF 4,2,0 LF 21,2,0 LF e. Dan moet er een prototype int guy (int x, int y); boven thomas staan, en de eerste parameter (x) van guy moet call by value zijn, evenals de eerste en tweede (a en b) van thomas (hier staan nu geen l-values). OPGAVE 3 a. bool meer (int Z[ ][n], int & i, int & j) { int tel; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) if ( Z[i][j] == 0 ) { tel = 0; if ( i > 0 && Z[i-1][j] == 0 ) tel++; if ( j > 0 && Z[i][j-1] == 0 ) tel++; if ( i < m-1 && Z[i+1][j] == 0 ) tel++; if ( j < n-1 && Z[i][j+1] == 0 ) tel++; if ( tel > 1 ) return true; }//if i = -1; j = -1; return false; }//meer b. void vul (int Z[ ][n], int i, int j, int waarde) { bool iets = true; Z[i][j] = waarde; while ( iets ) { iets = false; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) if ( Z[i][j] == 0 && ( ( i > 0 && Z[i-1][j] == waarde ) || ( j > 0 && Z[i][j-1] == waarde ) || ( i < m-1 && Z[i+1][j] == waarde ) || ( j < n-1 && Z[i][j+1] == waarde ) ) ) { Z[i][j] = waarde; iets = true; }//if }//while }//vul c. void allemeren (int Z[ ][n]) { int i, j, waarde = -1; while ( meer (Z,i,j) ) { vul (Z,i,j,waarde); waarde--; }//while }//allemeren OPGAVE 4 a. void voegtoe (object* & ingang, int x) { object* nieuw = new object; nieuw->info = x; if ( ingang == nullptr || ingang->info != x ) { nieuw->zelf = nullptr; nieuw->volg = ingang; }//if else { nieuw->zelf = ingang; nieuw->volg = ingang->volg; ingang->volg = nullptr; }//else ingang = nieuw; }//voegtoe b. void verwijder ( object* & ingang) { object* weg = ingang; if ( ingang != nullptr ) { if ( ingang->zelf == nullptr ) ingang = ingang->volg; else { ingang = ingang->zelf; ingang->volg = weg->volg; }//else delete weg; }//if }//verwijder c. int dubbel (object* ingang) { int teller = 0; object* horizontaal = ingang; object* verticaal; while ( horizontaal != nullptr ) { verticaal = horizontaal->zelf; while ( verticaal != nullptr ) { teller++; verticaal = verticaal->zelf; }//while horizontaal = horizontaal->volg; }//while return teller; }//dubbel d. Bij a en b moet er een & bij, de ingangspointer verandert (doorgaans). Bij c hoeft het niet, de ingangspointer verandert toch niet.