Uitwerking Tentamen Programmeermethoden 1 augustus 2011 OPGAVE 1 a. int jongst (int A[ ], int n) { int kl = A[0], i; for ( i = 1; i < n; i++ ) if ( A[i] < kl ) kl = A[i]; return kl; }//jongst b. void twee (int A[ ], int X, int & jonger, int & ouder, int n) { int i; jonger = -1; ouder = -1; for ( i = 0; i < n; i++ ) if ( A[i] > X && ( ouder == -1 || A[i] < ouder ) ) ouder = A[i]; else if ( A[i] < X && A[i] > jonger ) jonger = A[i]; }//twee c. int jongst2 (int A[ ], int n) { int jonger, ouder; twee (A,-1,jonger,ouder,n); return ouder; }//jongst2 d. void sorteer (int A[ ], int B[ ], int n) { int i, jonger, ouder = -1; for (i = 0; i < n; i++ ) { twee (A,ouder,jonger,ouder,n); B[i] = ouder; }//for }//sorteer e. De functie van d roept n keer de functie twee aan; twee doet tussen 2n-1 en 3n vergelijkingen. Totaal dus tussen 2*n*n (eigenlijk zelfs n*(2n-1)) en 3*n*n. 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: x, y in int f (int x, bool y) { ... Actueel: bij aanroep, bijvoorbeeld 7 en y in z = f (7,y); b. 2 5 5 5 2 2 2 5 5 5 2 2 2 5 5 2 5 0 35 35 2 5 0 c. 2 5 5 2 5 5 2 5 5 2 5 5 2 5 5 5 2 0 35 35 5 2 5 d. 6 6 6 5 5 5 4 4 4 3 3 3 2 2 2 1 1 1 0 0 0 42 42 0 e. Als x >= 0: x * (a + b), en anders 0. f. In orde als de parameters a en b van george call by value (zonder &) zijn. (Anders mag het niet.) En uiteraard ergens onder de functies gilbert en george (eventueel in die laatste). En het is geen recursie (tenzij het statement in de functie george zelf staat). OPGAVE 3 a. int telze (bool huis[ ][n], int rij) { int teller = 0, j; for ( j = 1; j < n-1; j++ ) if ( huis[rij][j-1] && ! huis[rij][j] && huis[rij][j+1] ) teller++; return teller; }//telze b. bool doorzichtig (bool huis[ ][n], int kol) { int i; for ( i = 0; i < m; i++ ) if ( huis[i][kol] ) return false; return true; }//doorzichtig c. int lang (bool huis[ ][n], int & p, int & q) { int langste = 0, counter, i, j, i1, j1; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) { i1 = i; j1 = j; counter = 0; while ( i1 < m && j1 < n ) { if ( huis[i1][j1] ) j1++; else i1++; counter++; }//while if ( counter > langste ) { langste = counter; p = i; q = j; }//if }//for return langste; }//lang OPGAVE 4 a. void voegtoe (iets* & begin, char let1, char let2) { iets* nieuw1 = new iets; iets* nieuw2 = new iets; nieuw1->let = let1; nieuw2->let = let2; nieuw1->vorig = NULL; nieuw2->vorig = nieuw1; begin->vorig = nieuw2; nieuw2->rechts2 = begin->rechts2->vorig; nieuw1->rechts2 = begin; begin = nieuw1; }//voegtoe b. void verwissel (iets* & begin) { iets* een = begin; iets* twee = begin->rechts2->vorig; een->vorig = twee; twee->vorig = NULL; een->rechts2->vorig = een; een->rechts2 = twee->rechts2; twee->rechts2 = twee->rechts2->vorig; begin = twee; }//verwissel c. void verwijder (iets* & begin) { begin = begin->rechts2; delete begin->vorig->vorig; delete begin->vorig; begin->vorig = NULL; }//verwijder d. Bij alle functies verandert de ingangspointer, er moet dus een & bij. Als bij b alleen de let-velden verwisseld worden hoeft er geen & bij (het mag wel). e. void repareer (iets* begin) { iets* loper = begin; iets* loper2 = begin->rechts2->vorig; iets* onthoud; while ( loper != NULL ) { onthoud = loper2->rechts2; loper2->rechts2 = loper->rechts2; loper->rechts2 = loper2; loper = loper2->rechts2; loper2 = onthoud; }//while }//repareer