25.01.2015 Aufrufe

Lösungen - Lehr- und Forschungsgebiet Informatik 2

Lösungen - Lehr- und Forschungsgebiet Informatik 2

Lösungen - Lehr- und Forschungsgebiet Informatik 2

MEHR ANZEIGEN
WENIGER ANZEIGEN
  • Keine Tags gefunden...

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

RHEINISCH-<br />

WESTFÄLISCHE<br />

TECHNISCHE<br />

HOCHSCHULE<br />

AACHEN<br />

LEHR- UND FORSCHUNGSGEBIET<br />

INFORMATIK 2<br />

RWTH Aachen · D-52056 Aachen · GERMANY<br />

http://programmierung.informatik.rwth-aachen.de<br />

LuFG<br />

<strong>Informatik</strong> II<br />

Prof. Dr. Jürgen Giesl<br />

Carsten Fuhs, Peter Schneider-Kamp, Stephan Swiderski<br />

Übung Programmierung WS 2007/08 - Blatt 3<br />

(Lösungsvorschlag)<br />

Aufgabe 1<br />

a) Ja. Eine Schleife der Form<br />

while (B) {<br />

P<br />

}<br />

lässt sich gleichwertig in die Form<br />

if (B) {<br />

do {<br />

P<br />

} while (B);<br />

}<br />

überführen.<br />

b) Ja. Eine Schleife der Form<br />

do {<br />

P<br />

} while (B);<br />

lässt sich gleichwertig in die Form


{<br />

}<br />

P;<br />

for ( ; B; ) {<br />

P<br />

}<br />

überführen.


Aufgabe 2<br />

Listing 1: Fibfor.java<br />

1 /∗ Das Programm berechnet zur Eingabe n die n−te Fibonacci −Zahl .<br />

2 ∗ Dabei werden ausser for −Schleifen keine anderen Schleifentypen<br />

3 ∗ verwendet .<br />

4 ∗<br />

5 ∗ Autor : Antje Nowack , Carsten Fuhs<br />

6 ∗ Erst ellt : 05.11.2001<br />

7 ∗ Letzte Aenderung : 05.11.2007<br />

8 ∗/<br />

9<br />

10 public class Fibfor {<br />

11<br />

12 public static void main (String [ ] arguments ) {<br />

13<br />

14 // Eingabe<br />

15 System .out .println (” Bitte geben Sie eine natuerliche Zahl ein : ” ) ;<br />

16 int n = IO .readInt ( ) ;<br />

17<br />

18 // a0 <strong>und</strong> a1 enthalten jeweils aufeinanderfolgende Fibonacci −Zahlen .<br />

19 int a0 = 0;<br />

20 int a1 = 1;<br />

21<br />

22 // res wird zum Zwischenspeichern benutzt <strong>und</strong> enthaelt am Ende<br />

23 // das Ergebnis<br />

24 int res = 0;<br />

25<br />

26 if (n == 1) {<br />

27 res = 1;<br />

28 }<br />

29<br />

30 // n − 1 Schleifendurchlaeufe<br />

31 for ( int j = 1; j < n ; ++j) {<br />

32<br />

33 // a0 enthaelt jeweils die zu j − 1 gehoerige Fibonacci −Zahl ,<br />

34 // a1 enthaelt die zu j gehoerige Fibonacci −Zahl , <strong>und</strong><br />

35 // res enthaelt die zu j + 1 gehoerige Fibonacci −Zahl .<br />

36 res = a0 + a1 ;<br />

37<br />

38 a0 = a1 ;<br />

39 a1 = res ;<br />

40 }<br />

41<br />

42 // Ausgabe<br />

43 System .out .println (”Die ” + n + ”−te Fibonacci−Zahl i s t ” + res ) ;<br />

44 }<br />

45 }


Listing 2: Fibwhile.java<br />

1 /∗ Das Programm berechnet zur Eingabe n die n−te Fibonacci −Zahl .<br />

2 ∗ Dabei werden ausser while −Schleifen keine anderen Schleifentypen<br />

3 ∗ verwendet .<br />

4 ∗<br />

5 ∗ Autor : Antje Nowack , Carsten Fuhs<br />

6 ∗ Erst ellt : 05.11.2001<br />

7 ∗ Letzte Aenderung : 05.11.2007<br />

8 ∗/<br />

9<br />

10 public class Fibwhile {<br />

11<br />

12 public static void main (String [ ] arguments ) {<br />

13<br />

14 // Eingabe<br />

15 System .out .println (” Bitte geben Sie eine natuerliche Zahl ein : ” ) ;<br />

16 int n = IO .readInt ( ) ;<br />

17<br />

18 // a0 <strong>und</strong> a1 enthalten jeweils aufeinanderfolgende Fibonacci −Zahlen .<br />

19 int a0 = 0;<br />

20 int a1 = 1;<br />

21<br />

22 // res wird zum Zwischenspeichern benutzt <strong>und</strong> enthaelt am Ende<br />

23 // das Ergebnis<br />

24 int res = 0;<br />

25<br />

26 if (n == 1) {<br />

27 res = 1;<br />

28 }<br />

29<br />

30 // Laufvariable<br />

31 int j = 1;<br />

32<br />

33 // n − 1 Schleifendurchlaeufe<br />

34 while (j < n) {<br />

35<br />

36 // a0 enthaelt jeweils die zu j − 1 gehoerige Fibonacci −Zahl ,<br />

37 // a1 enthaelt die zu j gehoerige Fibonacci −Zahl , <strong>und</strong><br />

38 // res enthaelt die zu j + 1 gehoerige Fibonacci −Zahl .<br />

39 res = a0 + a1 ;<br />

40<br />

41 a0 = a1 ;<br />

42 a1 = res ;<br />

43<br />

44 // Laufvariable um 1 erhoehen .<br />

45 ++j ;<br />

46 }<br />

47<br />

48 // Ausgabe<br />

49 System .out .println (”Die ” + n + ”−te Fibonacci−Zahl i s t ” + res ) ;


50 }<br />

51 }


Aufgabe 3<br />

Listing 3: Mastermind.java<br />

1 /∗ Das Programm simuliert das Spiel Mastermind.<br />

2 ∗ Hierbei erzeugt der Computer z u f aellig ein Geheimwort aus<br />

3 ∗ vier Zeichen , welches der Benutzer raten muss .<br />

4 ∗<br />

5 ∗ Autor : Antje Nowack , Carsten Fuhs , Stephan Swiderski<br />

6 ∗ Erst ellt : 05.11.2001<br />

7 ∗ Letzte Aenderung : 06.11.2007<br />

8 ∗/<br />

9<br />

10 public class Mastermind {<br />

11<br />

12 public static void main (String [ ] args ) {<br />

13 // Laufvariable fuer die do−while −Schleife<br />

14 int j = 1;<br />

15<br />

16 // g1 , g2 , g3 , g4 enthalten spaeter die Zeichen des Geheimwortes<br />

17 char g1 , g2 , g3 , g4 ;<br />

18<br />

19 /∗ eingabe i s t jeweils das geratene Wort ,<br />

20 ∗ <strong>und</strong> e1 , e2 , e3 , e4 sind seine Zeichen<br />

21 ∗/<br />

22 String eingabe ;<br />

23 char e1 , e2 , e3 , e4 ;<br />

24<br />

25 // erstes Zeichen des Geheimwortes aus dem Wertebereich { ’A’ , . . . , ’H’}<br />

26 g1 = Zufall .zufallszeichen ( ’H’ ) ;<br />

27<br />

28 /∗ Nun wird das zweite Zeichen des Geheimwortes bestimmt . Da g1 <strong>und</strong> g2<br />

29 ∗ nicht gleich sein duerfen , stehen fuer die Wahl von g2 nur noch<br />

30 ∗ 7 Zeichen zur Verfuegung . Um dies umzusetzen , wird wie f olgt<br />

31 ∗ vorgegangen :<br />

32 ∗ 1. Waehle ein Zeichen aus dem Wertebereich { ’A’ , . . . , ’G’}<br />

33 ∗ 2. Wenn das gewaehlte Zeichen < g1 ist , so i s t dies das zweite<br />

34 ∗ geratene Zeichen .<br />

35 ∗ 3. Sonst wird 1 hinzuaddiert , um das zweite Zeichen zu erhalten<br />

36 ∗ ( Beachte : Z.B. ’A’ + 1 == ’B ’).<br />

37 ∗<br />

38 ∗ Somit wird das zweite Zeichen aus dem Bereich<br />

39 ∗ { ’A’ , . . . , g1 −1, g1+1, . . . , ’H’} gewaehlt .<br />

40 ∗/<br />

41<br />

42 g2 = Zufall .zufallszeichen ( ’G’ ) ;<br />

43 if (g2 >= g1) {<br />

44 ++g2 ;<br />

45 }<br />

46<br />

47 /∗ Das Vorgehen fuer das dri tte Zeichen is t aehnlich dem Vorgehen


48 ∗ fuer das zweite Zeichen . Hier wird zunaechst ein Zeichen aus dem<br />

49 ∗ Wertebereich { ’A’ , . . . , ’F’} gewaehlt . Die moeglichen Zeichen sind<br />

50 ∗ diejenigen aus der Menge<br />

51 ∗ { ’A’ , . . . , g1 −1, g1+1, . . . , g2 −1, g2+1, . . . , ’H’} bzw .<br />

52 ∗ { ’A’ , . . . , g2 −1, g2+1, . . . , g1 −1, g1+1, . . . , ’H ’ }.<br />

53 ∗ Entsprechend muss das vom Zufallsgenerator erhaltene Zeichen<br />

54 ∗ um 1 erhoeht werden fuer den Bereich zwischen min(g1 , g2) <strong>und</strong><br />

55 ∗ max(g1 , g2) − 2 ( jeweils einschli esslich ) <strong>und</strong> um 2 erhoeht<br />

56 ∗ werden fuer den Bereich ab max(g1 , g2) − 1.<br />

57 ∗/<br />

58<br />

59 // kleinstesG = min(g1 , g2) <strong>und</strong> groesstesG = max(g1 , g2)<br />

60 int kleinstesG , groesstesG ;<br />

61 if (g2 >= g1) {<br />

62 kleinstesG = g1 ;<br />

63 groesstesG = g2 ;<br />

64 }<br />

65 else {<br />

66 kleinstesG = g2 ;<br />

67 groesstesG = g1 ;<br />

68 }<br />

69<br />

70 g3 = Zufall .zufallszeichen ( ’F ’ ) ;<br />

71 if (g3 >= kleinstesG ) {<br />

72 ++g3 ;<br />

73 }<br />

74 if (g3 >= groesstesG ) {<br />

75 ++g3 ;<br />

76 }<br />

77<br />

78 /∗ Das Vorgehen fuer das vierte Zeichen is t nun aehnlich dem Vorgehen<br />

79 ∗ fuer das dritte Zeichen . Hier wird zunaechst ein Zeichen aus dem<br />

80 ∗ Wertebereich { ’A’ , . . . , ’E’} gewaehlt . Die moeglichen Zeichen sind<br />

81 ∗ dann diejenigen aus der Menge { ’A’ , . . . , ’H’} \ {g1 , g2 , g3 }.<br />

82 ∗<br />

83 ∗ Hierfuer s o l l gelten :<br />

84 ∗ {kleinstesG , mittleresG , groesstesG } == {g1 , g2 , g3 } , wobei<br />

85 ∗ kleinstesG = min(g1 , g2 , g3 ) , groesstesG = max(g1 , g2 , g3) <strong>und</strong><br />

86 ∗ kleinstesG < mittleresG < groesstesG<br />

87 ∗/<br />

88<br />

89 int mittleresG ;<br />

90 if (g3 > kleinstesG ) {<br />

91 if (g3 > groesstesG ) {<br />

92 mittleresG = groesstesG ;<br />

93 groesstesG = g3 ;<br />

94 }<br />

95 else {<br />

96 mittleresG = g3 ;<br />

97 }


98 }<br />

99 else {<br />

100 mittleresG = kleinstesG ;<br />

101 kleinstesG = g3 ;<br />

102 }<br />

103<br />

104 g4 = Zufall .zufallszeichen ( ’E ’ ) ;<br />

105 if (g4 >= kleinstesG ) {<br />

106 ++g4 ;<br />

107 }<br />

108 if (g4 >= mittleresG ) {<br />

109 ++g4 ;<br />

110 }<br />

111 if (g4 >= groesstesG ) {<br />

112 ++g4 ;<br />

113 }<br />

114<br />

115<br />

116 /∗ Die folgende Schleife i s t die in der Aufgabenstellung geforderte<br />

117 ∗ do−while −Schleife .<br />

118 ∗/<br />

119 do {<br />

120<br />

121 /∗ Speichert , ob die Eingabe genau vier Zeichen aus dem erlaubten<br />

122 ∗ Alphabet enthaelt<br />

123 ∗/<br />

124 boolean korrekteEingabe ;<br />

125<br />

126 /∗ Die folgende do−while −Schleife i s t fuer die Eingabe zustaendig .<br />

127 ∗ Der Benutzer muss genau vier Zeichen eingeben .<br />

128 ∗ Ansonsten wird er zur erneuten Eingabe aufgefordert .<br />

129 ∗ Gleichzeitig wird das eingegebene Wort in seine Zeichen z erlegt .<br />

130 ∗/<br />

131 do {<br />

132 korrekteEingabe = true ;<br />

133 System .out .println (” Bitte geben Sie ein Wort aus vier Zeichen aus”<br />

134 + ” { ’A ’ , ’B ’ , . . . , ’H’} ein ! ” ) ;<br />

135 eingabe = IO .readLine ( ) ;<br />

136<br />

137 // Laenge der Eingabe ueberpruefen<br />

138 if (IO .length (eingabe ) != 4) {<br />

139 System .out .println (” Bitte geben Sie genau vier Zeichen ein ! ” ) ;<br />

140 korrekteEingabe = false ;<br />

141 }<br />

142 else {<br />

143 // ueberpruefen , ob die Eingabe nur erlaubte Zeichen enthaelt<br />

144 for ( int i = 0; i < 4; ++i) {<br />

145 char itesZeichenDerEingabe = IO .charAt (eingabe , i ) ;<br />

146 if ( ! (itesZeichenDerEingabe >= ’A’<br />

147 && itesZeichenDerEingabe


148 System .out . println (” Bitte geben Sie nur Zeichen aus”<br />

149 + ” { ’A ’ , ’B ’ , . . . , ’H’} ein ! ” ) ;<br />

150 korrekteEingabe = false ;<br />

151 break ;<br />

152 }<br />

153 }<br />

154 }<br />

155 }<br />

156 while ( ! korrekteEingabe ) ;<br />

157<br />

158 e1 = IO .charAt (eingabe , 0);<br />

159 e2 = IO .charAt (eingabe , 1);<br />

160 e3 = IO .charAt (eingabe , 2);<br />

161 e4 = IO .charAt (eingabe , 3);<br />

162<br />

163 /∗ In der Variable richtigeStellen wird die Anzahl der an der<br />

164 ∗ richtigen S telle geratenen Zeichen berechnet .<br />

165 ∗/<br />

166 int richtigeStellen = 0;<br />

167<br />

168 if (e1 == g1 ) {<br />

169 ++richtigeStellen ;<br />

170 }<br />

171 if (e2 == g2 ) {<br />

172 ++richtigeStellen ;<br />

173 }<br />

174 if (e3 == g3 ) {<br />

175 ++richtigeStellen ;<br />

176 }<br />

177 if (e4 == g4 ) {<br />

178 ++richtigeStellen ;<br />

179 }<br />

180<br />

181 System .out .println (” Richtige S tellen : ” + richtigeStellen );<br />

182<br />

183 /∗ In der Variable vorkommende wird die Anzahl der geratenen<br />

184 ∗ Zeichen berechnet , die zwar im Geheimwort auftreten ,<br />

185 ∗ jedoch nicht an der geratenen S telle .<br />

186 ∗/<br />

187 int vorkommende = 0;<br />

188<br />

189 if (e1 == g2 | | e1 == g3 | | e1 == g4 ) {<br />

190 ++vorkommende ;<br />

191 }<br />

192 if (e2 == g1 | | e2 == g3 | | e2 == g4 ) {<br />

193 ++vorkommende ;<br />

194 }<br />

195 if (e3 == g1 | | e3 == g2 | | e3 == g4 ) {<br />

196 ++vorkommende ;<br />

197 }


198 if (e4 == g1 | | e4 == g2 | | e4 == g3 ) {<br />

199 ++vorkommende ;<br />

200 }<br />

201<br />

202 System .out .println (”Auftretende Zeichen : ” + vorkommende ) ;<br />

203<br />

204 /∗ Wenn alle Zeichen r ichtig <strong>und</strong> jeweils an der richtigen St elle<br />

205 ∗ geraten wurden , dann hat der Benutzer das Geheimwort erraten .<br />

206 ∗ Die Schleife wird verlassen .<br />

207 ∗/<br />

208 if (richtigeStellen == 4) {<br />

209 break ;<br />

210 }<br />

211<br />

212 // Die Nummer des Rateversuchs wird um 1 erhoeht .<br />

213 ++j ;<br />

214 }<br />

215 // Der Benutzer darf zwoelfmal raten .<br />

216 while (j


Aufgabe 4<br />

a) 〈n ≥ 0〉<br />

〈n ≥ 0 ∧ 0 = 0〉<br />

i = 0;<br />

〈n ≥ 0 ∧ i = 0〉<br />

〈n ≥ 0 ∧ i = 0 ∧ 0 = 0〉<br />

res = 0;<br />

〈n ≥ 0 ∧ i = 0 ∧ res = 0〉<br />

〈i ≤ n ∧ res = n ∗ i〉<br />

while (i < n) {<br />

〈i ≤ n ∧ res = n ∗ i ∧ i < n〉<br />

〈i < n ∧ res + n = n ∗ i + n〉<br />

res = res + n;<br />

〈i < n ∧ res = n ∗ i + n〉<br />

〈i + 1 ≤ n ∧ res = n ∗ (i + 1)〉<br />

i = i + 1;<br />

〈i ≤ n ∧ res = n ∗ i〉<br />

}<br />

〈i ≤ n ∧ res = n ∗ i ∧ i ≮ n〉<br />

〈res = n 2 〉


) Eine Variante ist V = n − i, denn aus der Schleifenbedingung i < n folgt<br />

n − i ≥ 0. Somit:<br />

res = res + n;<br />

i = i + 1;<br />

〈n − i = m ∧ i < n〉<br />

〈n − (i + 1) < m〉<br />

〈n − (i + 1) < m〉<br />

〈n − i < m〉<br />

Damit ist die Terminierung der einzigen Schleife in P gezeigt.<br />

c) Für n = 46341 nimmt die int-Variable res einen negativen Wert an. Der<br />

Gr<strong>und</strong> dafür ist, dass das eigentlich erwünschte Ergebnis 46341 2 = 2147488281<br />

größer ist als der maximal in einem int darstellbare Wert von 2 31 − 1. Bei der<br />

obigen Verifikation gehen wir jedoch vereinfachend davon aus, dass beliebig<br />

große ganze Zahlen dargestellt werden können.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!