Prof. Heike Wehrheim und Mitarbeiter Paderborn, den 24. November 2008 Musterlösung zur Vorlesung Grundlagen der Programmierung 1 WS 2008/09 Blatt 6 AUFGABE 1: Die rekursive Methode tueEtwas gibt für jede positive Zahl n die Zahlenfolge n n-1 n-2 ... 1 1 2 ... n-1 n aus. Zunächst wird durch System.out.print(" "+zahl); zahl = zahl - 1; die übergebene Zahl ausgegeben und dekrementiert. Nachfolgend erfolgt der rekursive Aufruf tueEtwas(zahl); Am Ende wird nach der Inkrementierung durch zahl = zahl + 1; System.out.print(" "+zahl); wieder die Zahl selbst ausgegeben. Innerhalb des rekursiven Aufrufs werden alle Zahlen zwischen n-1 und 1 sowie 1 und n-1 ausgegeben. (0.5 P) Grafisch stellt sich der Aufruf tueEtwas(3) wie folgt dar und führt zu folgenden Ausgaben: (1.5 P) AUFGABE 2: a) Die Funktionsdefinition kann 1:1 in die Implementierung übernommen werden. Negative Zahlen sind nicht zu betrachten. 1 public c l a s s EineFunktion { 2 // r e k u r s i v e I m p l e m e n t i e r u n g d e r Funktion d e s A u f g a b e n b l a t t e s public s t a t i c int f ( int z a h l ) { // ( 0 . 5 P) // A b b r u c h f a l l : Z a h l i s t 0 ( 0 . 5 P) i f ( z a h l ==0) return 0 ; // A b b r u c h f a l l : z a h l i s t 1 ( 0 . 5 P) i f ( z a h l ==1) return 2 ; // r e k u r s i v e r Aufruf , f a l l s Z a h l >1 i s t (1 P) return ( 2 ∗ f ( z a h l −2)+5) ; 3 4 5 6 7 8 9 10 11 12 13 } 14 15 // T e s t f u n k t i o n public s t a t i c void main ( S t r i n g [ ] a r g s ) { int z a h l = I n t e g e r . p a r s e I n t ( a r g s [ 0 ] ) ; // A u f r u f d e r r e k u r s i v e n Funktion f u e r d i e e i n g e l e s e n e Z a h l System . out . p r i n t l n ( ” f angewandt a u f ”+z a h l+” l i e f e r t ”+f ( z a h l ) ) ; } 16 17 18 19 20 21 22 23 } b) Die Rekursion erfolgt über die Variable n, Abbruchfall ist n==0. Insbesondere ist dann eine 1 zurückzugeben. 1 public c l a s s Potenz { 2 3 4 5 6 7 8 9 10 11 // r e k u r s i v e I m p l e m e n t i e r u n g d e r Funktion pow public s t a t i c int pow ( int x , int n ) { // ( 0 . 5 P) // A b b r u c h f a l l : n=0, r e t u r n : 1 ( 1 . 0 P) i f ( n==0) return 1 ; else // r e k u r s i v e r Aufruf , f a l l s Z a h l >0 i s t (1 P) return pow ( x , n−1)∗x ; } 12 13 14 // T e s t f u n k t i o n public s t a t i c void main ( S t r i n g [ ] a r g s ) { int x = I n t e g e r . p a r s e I n t ( a r g s [ 0 ] ) ; int n = I n t e g e r . p a r s e I n t ( a r g s [ 1 ] ) ; // A u f r u f d e r r e k u r s i v e n Funktion f u e r d i e e i n g e l e s e n e Z a h l System . out . p r i n t l n ( x+” hoch ”+n+” e r g i b t ”+pow ( x , n ) ) ; } 15 16 17 18 19 20 21 22 } AUFGABE 3: Die Hauptaufgabe besteht darin, die Methode teilerSumme zu implementieren. Dabei ist der Abbruchfall obergrenze==0 auch notwendig, um die Zahl 1 auf die Bedingung perfekt hin zu prüfen. In der Rekursion müssen zwei Fälle unterschieden werden: Teiler werden aufsummiert, Nichtteiler nicht. Innerhalb von perfekt muss nur noch die Bedingung an perfekte Zahlen überprüft werden, eine Zahl ist genau dann perfekt, wenn teilerSumme(zahl,zahl-1)==zahl gilt. 1 public c l a s s P e r f e k t { 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // r e k u r s i v e I m p l e m e n t i e r u n g d e r Funktion teilerSumme ( Gesamt 3 P) public s t a t i c int teilerSumme ( int z a h l , int o b e r g r e n z e ) { // A b b r u c h f a l l o b e r g r e n z e==0 ( 1 . 0 P) i f ( o b e r g r e n z e ==0) return 0 ; // r e k u r s i v e Berechnung − Bedingung ( 0 . 5 P) i f ( z a h l%o b e r g r e n z e ==0) // T e i l e r g e f u n d e n : Aufsummierung und r e k u r s i v e r A u f r u f (1 P) return o b e r g r e n z e+teilerSumme ( z a h l , o b e r g r e n z e −1) ; else // k e i n T e i l e r : r e k u r s i v e r A u f r u f ohne Aufsummierung ( 0 . 5 P) return teilerSumme ( z a h l , o b e r g r e n z e −1) ; } 16 17 18 19 20 21 22 // r e k u r s i v e I m p l e m e n t i e r u n g d e r Funktion p e r f e k t ( Gesamt 1 P) public s t a t i c boolean p e r f e k t ( int z a h l ) { // Bedingung an p e r f e k t e Z a h l : teilerSumme b i s z u r Z a h l ohne // d i e Z a h l s e l b s t e r g i b t Z a h l (1 P) return ( teilerSumme ( z a h l , z a h l −1)==z a h l ) ; } 23 24 25 26 27 28 29 30 31 // T e s t f u n k t i o n : Welche Zahlen z w i s c h e n 1 und 200 s i n d p e r f e k t ? (1 P) public s t a t i c void main ( S t r i n g [ ] a r g s ) { // S c h l e i f e ü b e r a l l e Zahlen ( 0 . 5 P) for ( int i =1; i <=200; i ++) // Bedingung f ü r p e r f e k t e Z a h l ( 0 . 5 P) if ( perfekt ( i ) ) // Ausgabe System . out . p r i n t l n ( i+” i s t e i n e p e r f e k t e Zahl . ” ) ; 32 } 33 34 35 }