Está en la página 1de 19

Aufgabensammlung

Tutorium zur Einfuhrung in die Programmierung


- Praktischer Teil: Java-Programmierung -

Inhaltsverzeichnis
1

Kontrollstrukturen

Methoden

Rekursion

11

Felder

13

OOP

17

1. 2

Kontrollstrukturen

Aufgabe 1.1
Schreiben Sie ein Java-Programm, das den Wert einer Variablen vom Typ int in Binardarstellung ausgibt, d.h. als
Folge von Nullen und Einsen. Verwenden Sie dazu in geeigneter Weise die beiden Operatoren % und / und nutzen
Sie die Tatsache aus, dass ein Wert vom Typ int 32 bit hat.
Hinweis:
Eine while-Schleife hat in Java folgende Syntax:
while ( boolescher Ausdruck ) { Anweisung }
Denken Sie daran, dass der +-Operator, wenn man ihn auf eine int- und eine String-Variable anwendet, die intVariable in einen String umwandelt und dann verkettet.
Losung zu 1.1
Das Programm
public cl as s BinaerTest {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) {
in t eingabe ;
int rest ;
int i ; / / Schleifenzaehler
S t r i n g s ; / / f u e r d i e Ausgabe
/ / E in g a b e m i t Wert b e l e g e n
eingabe = 49;
/ / I n i t i a l i s i e r u n g d e r Ausgabe
s = ;
// Schleife
i = 1;
w h i l e ( i <= 3 2 ) {
r e s t = e i n g a b e %2; / / B er ech n u n g e i n e r B i n a e r s t e l l e
eingabe = eingabe / 2 ;
/ / b e r e c h n e t e B i n a e r s t e l l e h i n t e n an Ausgabe a n h a en g en
s = rest + s ;
i = i +1; / / s c h l e i f e n z a e h l e r erhoehen
}
/ / Ausgabe d e s E r g e b n i s s e s
System . o u t . p r i n t l n ( s ) ;
}
}

liefert die Ausgabe 00000000000000000000000000111101.


Aufgabe 1.2
Welche Ausgabe liefert folgendes Java-Programm?
p u b l i c c l a s s Var1 {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int a = 1 , b = 2 , c = 3;
c = c + a + b;
a = c a b;
b = c a b;
c = c a b;
System . o u t . p r i n t l n ( a = + a ) ;
System . o u t . p r i n t l n ( b = + b ) ;
System . o u t . p r i n t l n ( c = + c ) ;
}
}

Losung zu 1.2
Die folgende Tabelle zeigt die Belegung der Variablen vor bzw./ nach den angegebenen Anweisungen:

1. 3

a
1

b
2

c
3

c=c+a+b
1

a=cab

b=cab

c=cab

Das Programm liefert also die Ausgabe


a = 3
b = 1
c = 2

Aufgabe 1.3
In folgendem Programm werden zwei Integervariablen mit Eingabewerten aus der Kommandozeile belegt und
anschlieend die eingegebenen Werte wieder ausgegeben.
p u b l i c c l a s s I n tA d d {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) {
int i1
int i2 ;
/ / Belegung der Variablen mit Eingabewerten
i1 = In t e ge r . p a r s e I n t ( args [ 0 ] ) ;
i2 = In t e ge r . p a r s e I n t ( args [ 1 ] ) ;
/ / Ausgabe d e r V a r i a b l e n w e r t e
System . o u t . p r i n t l n ( i 1 : + i 1 ) ;
System . o u t . p r i n t l n ( i 2 : + i 2 ) ;
}
}

Beim Programmstart mussen dann entsprechende Werte (Integer-Konstanten) angegeben werden.


Beispiel:

Ubersetzen
mit javac IntAdd.java
Starten mit java IntAdd 23 65
liefert die Ausgabe:
i1: 23
i2: 65

In der Folge konnen bei jedem Programmaufruf andere Werte angegeben werden, ohne dass ein erneutes Uberstzen
notwendig ware.
Erganzen Sie das angegebene Programm um eine Methode, die die beiden Eingabewerte addiert. Dise Methode
soll im Hauptprogramm aufgerufen und das Ergebnis ausgegeben werden.
Losung zu 1.3
Die Additionsmethode bekommt zwei Integerwerte als Parameter u bergeben und liefert einen Interwert als Ergebnis zuruck, der Methodenkopf ist also
public s t a t i c int addiere ( int x , int y )

Der Rumpf soll nun die Summe berechnen. Dazu kann entweder eine lokale (Hilfs-)variabel benutzt werden:
{
int z ;
z = x + y;
return z ;
}

oder man verzichtet auf die Hilfsvariable:

1. 4

{
return x + y ;
}

Im Hauptprogramm fugen wir den Methodenaufruf summe = addiere(i1 ,

i2 ) ;

ein.

Insgesamt sieht das Programm dann so aus:


p u b l i c c l a s s I n tA d d {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) {
i n t i1 ; / / e r s t e r Eingabewert
i n t i2 ; / / z w e i t e r Eingabewert
i n t summe ; / / E r g e b n i s v a r i a b l e
/ / B e l e g u n g m i t den E i n g a b e w e r t e n
i1 = In t e ge r . p a r s e I n t ( args [ 0 ] ) ;
i2 = In t e ge r . p a r s e I n t ( args [ 1 ] ) ;
/ / Additionsmethode aufrufen
summe = a d d i e r e ( i1 , i 2 ) ;
/ / Ergebnisausgabe
System . o u t . p r i n t l n ( i 1 : + i 1 ) ;
System . o u t . p r i n t l n ( i 2 : + i 2 ) ;
System . o u t . p r i n t l n ( Summe : + summe ) ;
}
/ / Additionsmethode d e f i n i e r e n
public s t a t i c int addiere ( int x , int y ) {
int z ;
z = x + y;
return z ;
/ / e s g e h t auch m i t n u r e i n e r A n w eis u n g und ohne d i e H i l f s v a r i a b l e z
/ / r e t u r n ( x+y ) ;
}
}

Aufgabe 1.4
Seit Jahrtausenden versuchen die Menschen, die Kreiszahl , die definiert ist als Kreisumfang dividiert durch
Kreisdurchmesser, moglichst exakt zu bestimmen.
So rechneten die Babylonier ca. 2000 v. Chr. mit dem Wert 3 81 ,
2

in Agypten
ist seit ungefahr der gleichen Zeit der Wert ( 16
berliefert,
9 ) u

in China wurde seit ca. 250 n. Chr. 10 benutzt


und in Europa ist seit Archimedes (ca. 250 v. Chr.) 3 71 eine bekannte Naherung.
Bestimmen Sie diese Werte und berechnen Sie die jeweilige Abweichung von dem auf 15 Dezimalstellen exakten
Wert, wie er in der Java-Konstanten Math.PI zur Verfugung gestellt wird.
Hinweis:
Die Wurzelfunktion konnen Sie in Java mittels Math.sqrt( einzusetzender Wert) aufrufen.
Losung zu 1.4
public cl as s piAntik {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
d o u b le
d o u b le
d o u b le
d o u b le

piBabylon ;
piAegypten ;
piChina ;
piEuropa ;

piBabylon = 3.0 + ( 1 . 0 / 8 . 0 ) ;
piAegypten = 16.016.0 / ( 9 . 0 9 . 0 ) ;
p i C h i n a = Math . s q r t ( 1 0 . 0 ) ;
piEuropa = 3.0 + 1 . 0 / 7 . 0 ;

1. 5

System .
System .
System .
System .
System .
System .
System .
System .
System .

out .
out .
out .
out .
out .
out .
out .
out .
out .

p r i n t l n ( Java :
p r i n t ( B ab y lo n :
p r i n t l n ( \ t \ t \ t
p r i n t ( A eg y p ten :
p r i n t l n ( \ t \ t \ t
p r i n t ( C h in a :
p r i n t l n ( \ t \ t \ t
p r i n t ( Europa :
p r i n t l n ( \ t \ t \ t

+ Math . P I ) ;
+ piBabylon ) ;
Abweichung : + ( Math . P I
+ piAegypten ) ;
Abweichung : + ( Math . P I
+ pi ) ;
Abweichung : + ( Math . P I
+ piEuropa ) ;
Abweichung : + ( Math . P I

piBabylon ) ) ;
piAegypten ) ) ;
piChina ) ) ;
piEuropa ) ) ;

}
}

Aufgabe 1.5
Ihnen wird folgender Handytarif angeboten:
Der Basispreis betragt 22,98 Euro/Monat, darin sind 30 freie Gesprachsminuten enthalten. Jede daruber hinausgehende Gesprachsminute kostet 0,248 Euro.
Schreiben Sie ein Java-Programm, das den Rechnungsbetrag berechnet. Die Anzahl der Gesprachsminuten soll
beim Programmstart in der Kommandozeile als Parameter u bergeben werden.
Losung zu 1.5
public cl as s TarifB {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
d o u b le p r e i s P r o E i n h e i t = 0 . 2 4 8 ;
d o u b le g r u n d g e b = 2 2 . 9 8 ;
in t dauer ;
d o u b le b e t r a g ;
dauer = I n te g e r . pa rs e I n t ( args [ 0 ] ) ;
i f ( dauer > 30)
b etr ag = ( dauer 30) p r e i s P r o E i n h e i t + grundgeb ;
else
b etr ag = grundgeb ;
System . o u t . p r i n t l n ( R e c h n u n g s b e t r a g : + b e t r a g + Euro ) ;
}
}

Das Programm liefert beim Aufruf mit 30 bzw. 31 Minuten die Betrage:
>java TarifB 30
Rechnungsbetrag: 22.98 Euro
>java TarifB 31
Rechnungsbetrag: 23.228 Euro

Aufgabe 1.6
Wandeln Sie die Zahlschleife des folgenden Beispiels in eine a quivalente fugesteuerte Schleife um. Testen Sie
Ihr Programm mit den Eingabewerten n = 0, n = 1 und n = 5.
i n t i , n , summe ;
summe = 0 ;
f o r ( i = 1 ; i <= n ; i = i +1 )
summe = summe + i ;

Losung zu 1.6
p u b l i c c l a s s ForDo {
public
int
int
int
int

s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i;
summeFor ;
summeDoWhile ;
n;

n = Integer . parse Int ( args [0]) ;

1. 6

/ / B er ech n u n g m i t f o r S c h l e i f e
summeFor = 0 ;
f o r ( i = 1 ; i <= n ; i = i +1 )
summeFor = summeFor + i ;
/ / B er ech n u n g m i t dow h i l e S c h l e i f e
summeDoWhile = 0 ;
i = 1;
i f ( i <= n ) {
do {
summeDoWhile = summeDoWhile + i ;
i = i +1;
} w h i l e ( i <= n ) ;
}
System . o u t . p r i n t l n ( Summe von 1 b i s + n ) ;
System . o u t . p r i n t l n ( E r g e b n i s f o r S c h l e i f e : + summeFor ) ;
System . o u t . p r i n t l n ( E r g e b n i s dow h ile S c h l e i f e : + summeDoWhile ) ;
}
}

Das Programm liefert die korrekte Ausgabe


> java ForDo 5
Summe von 1 bis 5
Ergebnis for-Schleife: 15
Ergebnis do-while-Schleife: 15
> java ForDo 1
Summe von 1 bis 1
Ergebnis for-Schleife: 1
Ergebnis do-while-Schleife: 1
> java ForDo 0
Summe von 1 bis 0
Ergebnis for-Schleife: 0
Ergebnis do-while-Schleife: 0

Aufgabe 1.7 (EulerE)


Die Eulersche Zahl e hat folgende Reihendarstellung:

X
1
e=
k!
k=0

Schreiben Sie ein Java-Programm, das den Wert dieser Summe berechnet
a) bis zum 100. Reihenglied
b) bis der neue Summand < 0.00000001 ist.
Losung zu 1.7
public c l a s s EulerE {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
d o u b le e , summand ;
int k ;
/ / L o es u n g f u e r T e i l a )
e = 1.0;
summand = 1 . 0 ;
f o r ( k = 1 ; k < 1 0 0 ; k = k +1 ) {
summand = summand / k ;
e = e + summand ;
}
System . o u t . p r i n t l n ( N aeh er u n g f u e r e n ach + k + I t e r a t i o n e n : + e ) ;
/ / L o es u n g f u e r T e i l b )
e = 1.0;
summand = 1 . 0 ;

2. 7

k = 1;
do {
summand = summand / k ;
e = e + summand ;
k = k +1;
} w h i l e ( summand >= 0 . 0 0 0 0 0 0 0 1 ) ;
System . o u t . p r i n t l n ( N aeh er u n g f u e r e n ach + k + I t e r a t i o n e n : + e ) ;
}
}

Methoden

Aufgabe 2.1
Die harmonische Reihe ist definiert als unendliche Summe

X
1
1 1 1
= 1 + + + + ...
k
2 3 4

k=1

Implementieren Sie eine Methode, die die harmonische Reihe bis zu einer vorgegebenen Anzahl von Reihengliedern berechnet.
Sie konnen Ihre Methode in diese Testumgebung einbetten:
public c l a s s HarmonischeReihe {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int n ;
d o u b le sum ;
n = Integer . parse Int ( args [0]) ;
/ / Methodenaufruf
/ / sum = . . . . ;
System . o u t . p r i n t l n ( sum ) ;
}
/ / Methodendefinition
}

Losung zu 2.1
public c l a s s HarmonischeReihe {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int n ;
d o u b le sum ;
n = Integer . parse Int ( args [0]) ;
sum = b e r e c h n e R e i h e ( n ) ;
System . o u t . p r i n t l n ( sum ) ;
}

p u b l i c s t a t i c d o u b le b e r e c h n e R e i h e ( i n t n ) {
d o u b le s = 0 . 0 ;
f o r ( i n t k = 1 ; k <= n ; k ++)
s = s + 1.0/k;
return s ;

2. 8

}
}

Beispielaufrufe und Ergebnisse:


> jav a HarmonischeReihe 2
1.5
> j a v a H a r m o n i s c h e R e i h e 10
2.9289682539682538

Aufgabe 2.2
Fur ein Seminar mu jeder Teilnehmer eine schriftliche Hausarbeit anfertigen und einen mundlichen Vortrag halten. Dafur sind jeweils maximal 10 Punkte erhaltlich. Zur Ermittlung der Gesamtpunktzahl wird die Punktzahl
der Hausarbeit mit 3, die des Vortrags mit 2 multipliziert. Das folgende Java-Programm soll die Gesamtpunktzahl
eines Studenten berechnen, der fur die Hausarbeit 5 Punkte, fur den Vortrag 8 Punkte erhalten hat. Was geschieht?
Wie kann man den Fehler beheben?
public c l a s s Seminarunkte {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ]
int hausarbeit = 5 , vortrag =
bewerten ( h au s ar b eit , v o r tr ag ,
System . o u t . p r i n t l n ( e r r e i c h t e
}

args ){
8 , summe = 0 ;
summe ) ;
P u n k t e : + summe ) ;

public s t a t i c void bewerten ( i n t h , i n t v , i n t s ) {


h = h 3;
v = v 2;
s = h + v;
return ;
}
}

Losung zu 2.2
Da Kopien der Werte der Parameter an das Unterprogramm u bergeben werden (call by value), bleiben die Inhalte

der Speicherzellen im aufrufenden Programm unverandert. Ubergabeparameter


sind also nicht geeignet, um Werte
an das aufrufende Programm zuruckzuliefern. Statt dessen kann ein eigener Ruckgabewert vereinbart werden:
public c l a s s Seminarunkte {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i n t h a u s a r b e i t = 5 , v o r t r a g = 8 , summe = 0 ;
summe = b e w e r t e n ( h a u s a r b e i t , v o r t r a g ) ;
System . o u t . p r i n t l n ( e r r e i c h t e P u n k t e : + summe ) ;
}
public s t a t i c i n t bewerten ( i n t h , i n t v ) {
h = h 3;
v = v 2;
return h + v ;
}
}

Aufgabe 2.3
Ein Mobilfunkanbieter stellt Ihnen 3 Tarife zur Wahl:
Tarif 1 kostet 11,75 Euro Grundgebuhr im Monat, zusatzlich kostet jede Gesprachsminute 50 Cent.
Tarif 2 kostet 19,25 Euro Grundgebuhr, dafur schlagt die Gesprachsminute aber nur mit 25 Cent zu Buche.
Tarif 3 hat eine monatliche Grundgebuhr von 22,75 Euro, darin sind 30 Gesprachsminuten pro Monat frei. Erst
jede daruber hinaus gehende Minute kostet dann 0,375 Euro.
Schreiben Sie ein Java-Programm, das fur jeden Tarif die Monatsrechnung (fur 10 bzw. 20, 30, 40, . . . 100 Minuten
Gesprache im Monat) erstellt.
Definieren Sie fur jeden Tarif eine eigene Methode.

2. 9

Losung zu 2.3
public cl as s TarifRechner{
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i n t minute ;
System . o u t . p r i n t l n ( Min \ t T a r i f 1 \ t T a r i f 2 \ t T a r i f 3 ) ;
f o r ( m i n u t e = 1 0 ; m i n u t e <= 100 ; m i n u t e = m i n u t e + 1 0 ) {
System . o u t . p r i n t l n ( m i n u t e + \ t + t a r i f 1 ( m i n u t e ) + \ t \ t + t a r i f 2 ( m i n u t e ) +
\ t \ t + t a r i f 3 ( minute ) ) ;
}
}
p u b l i c s t a t i c d o u b le t a r i f 1 ( i n t min ) {
r e t u r n ( 1 1 . 7 5 + min 0 . 5 ) ;
}
p u b l i c s t a t i c d o u b le t a r i f 2 ( i n t min ) {
r e t u r n ( 1 9 . 2 5 + min 0 . 2 5 ) ;
}
p u b l i c s t a t i c d o u b le t a r i f 3 ( i n t min ) {
i f ( min <= 2 0 )
return 2 2 . 7 5 ;
else
r e t u r n 2 2 . 7 5 + ( min 3 0 ) 0 . 3 7 5 ;
}
}

Das Programm liefert folgende Ergebnisse:


Min
10
20
30
40
50
60
70
80
90
100

Tarif 1
16.75
21.75
26.75
31.75
36.75
41.75
46.75
51.75
56.75
61.75

Tarif 2
21.75
24.25
26.75
29.25
31.75
34.25
36.75
39.25
41.75
44.25

Tarif 3
22.75
22.75
22.75
26.5
30.25
34.0
37.75
41.5
45.25
49.0

Aufgabe 2.4
Programmieren Sie das Newton-Verfahren zur Berechnung von Nullstellen einer Funktion: Beginnend bei einem
Startwert x0 wird xi+1 mittels der Iterationsvorschrift
xi+1 = xi

f (xi )
f (xi )

berechnet, bis |f (xi )| < fur eine vorgegebene Genauigkeit > 0 ist. Verwenden Sie f (x) = x2 2 mit dem
Startwert x0 = 1 und die Genauigkeit = 1.0 1015 .
Zur Erinnerung:
Fur f (x) = x2 2 ist die Ableitung gegeben durch f (x) = 2x.
Verwenden Sie je ein Unterprogramm zur Berechnung von f (x), von f (x) und eines fur die Berechnung des
Absolutbetrags.
*) Wieviele Schleifendurchlaufe benotigt Ihr Programm? Wie oft wird dabei die Funktion f und die Funktion
f aufgerufen?
**) Auch die Ableitung einer Funktion an einer Stelle x kann numerisch berechnet werden, indem die Naherung
(x)
fur d 0 bestimmt wird.
f (x) = f (x+d)f
d

Andern Sie Ihr Unterprogramm zur Berechnung der Ableitung so ab, dass d (beginnend mit d = 1) d solange
halbiert wird, bis zwei aufeinanderfolgende Naherungswerte einen Abstand kleiner als haben.

2. 10

Losung zu 2.4
p u b l i c c l a s s NewtonNS {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
d o u b le x = 1 ;
d o u b le e p s = 1 . 0 e 15;
while ( ( abs ( f ( x ) ) > eps ) & ( f s ( x ) != 0) ) {
x = x ( f (x) / fs (x) ) ;
System . o u t . p r i n t l n ( x = + x +
f (x) = + f (x) ) ;
}
}
p u b l i c s t a t i c d o u b le f ( d o u b le x ) {
r e t u r n xx 2;
}
p u b l i c s t a t i c d o u b le f s ( d o u b le x ) {
r e t u r n 2 x ;
}
p u b l i c s t a t i c d o u b le a b s ( d o u b le x ) {
i f ( x < 0)
x = x ;
return x ;
}
}

zu *) Um die Anzahl der Schleifendurchlaufe zu ermitteln, kann eine Integer-Variable eingebaut werden. Die
Funktion f wird in jedem Durchlauf dreimal aufgerufen (einmal zum Auswerten der Schleifen-AbbruchBedingung, einmal zu Berechnung des neuen Naherungswertes und einmal fur die Ausgabe. Die Funktion f
wird in jedem Durchlauf zweimal aufgerufen. Das sollte durch Einfuhrung von Zwischenvariablen verbessert
werden.
**) Dazu ersetzen wir die Methode fs durch
p u b l i c s t a t i c d o u b le f s ( d o u b le x ) {
d o u b le d = 1 . 0 ;
d o u b le f1 , f2 , f x ;
d o u b le e p s = 1 . 0 e 15;
fx = f ( x ) ;
f 2 = ( f ( x+d ) f x ) / d ;
do {
f1 = f2 ;
d = 0.5 d ;
f 2 = ( f ( x+d ) f x ) / d ;
} while ( abs ( f1 f2 ) > eps ) ;
return f2 ;
}

3. 11

Rekursion

Aufgabe 3.1
a) In der Vorlesung haben Sie eine rekursive Java-Methode zur Berechnung der Fibonacci-Zahlen kennengelernt,
deren Berechnungsaufwand in O(2n ) liegt. Nehmen Sie an, die Anzahl der Arbeitsschritte zur Berechnung der
n-ten Fibonaccizahl sei exakt = 2n . Wie lange wird fur die Berechnung der 40. Fibonaccizahl benotigt, wenn
100.000 Arbeitsschritte pro Sekunde ausgefuhrt werden konnen?
b) Schreiben Sie eine iterative Java-Methode zur Berechnung der Fibonaccizahlen.
c) Welche Komplexitat hat Ihr Algorithmus? Die wievielte Fibonaccizahl konnte (bei 100.000 Arbeitsschritten/Sekunde) in einer Sekunde berechnet werden?
Losung zu 3.1

a) Der Aufwand betragt 240 1.0995116 1012 Arbeitsschritte, bei 100.000 Schritten/Sekunde werden dafur ca.
10995116 Sekunden benotigt, das sind ungefahr 3054 Stunden.
b)

public c l a s s Fib {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int n = Integer . parseInt ( args [0]) ;
System . o u t . p r i n t l n ( f i b I t e r a t i v ( n ) ) ;
}
public s t a t i c int f i b I t e r a t i v ( int n ) {
i n t i , f0 , f1 , f 2 = 0 ;
i f ( n < 2)
return 1;
else {
f0 =1;
f1 =1;
i = 1;
while ( i < n ) {
f2 = f0 + f1 ;
f0 = f1 ;
f1 = f2 ;
i = i +1;
}
return f2 ;
}
}
}

c) Der Arbeitsaufwand liegt in O(n). Wenn wir annehmen, dass die Proportionalitatskonstante c = 10 ist, konnen
= 10000 Fibonaccizahlen berechnet werden.
in einer Sekunde n = 100000
10
Aufgabe 3.2
Programmieren Sie je eine iterative und eine rekursive Methode zur Berechnung von xy fur x, y N0 .
Zur Erinnerung: x0 = 1.
Losung zu 3.2
public cl as s Potenzberechnung {
public
int
int
int

s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
pr ;
/ / E r g e b n i s d e r r e k u r s i v e r n B er ech n u n g
pi ;
/ / E r g b e n i s d e r i t e r a t i v e n B er ech n u n g
x;
/ / Eingabewerte
int y ;

x = Integer . parse Int ( args [0]) ;


y = Integer . parse Int ( args [1]) ;
p r = p o ten zR e k ( x , y ) ;
System . o u t . p r i n t l n ( x + hoch + y + = + p r ) ;
pi = po te n zI t (x , y ) ;
System . o u t . p r i n t l n ( x + hoch + y + = + p i ) ;

4. 12

}
p u b l i c s t a t i c i n t p o ten zR ek ( i n t x , i n t y ) {
/ / r e k u r s i v e Methode z u r B er ech n u n g d e r P o t e n z von x und y
i n t potenz ; / / Zwischenwert
i f ( y == 0 )
potenz = 1;
else
p o t e n z = x p o ten zR e k ( x , y 1) ;
return potenz ;
}
public s t a t i c int p ot e nz It ( int x , int y ) {
/ / i t e r a t i v e Methode z u r B er ech n u n g d e r P o t e n z von x und y
in t potenz ;
/ / Zwischenwert
potenz = 1;
f o r ( i n t i = 1 ; i <= y ; i = i +1 )
potenz = x potenz ;
return potenz ;
}
}

Aufgabe 3.3
Schreiben Sie eine rekursive Methode zur Berechnung des ggTs zweier naturlichen Zahlen ( 0). Nutzen Sie
dabei folgenden Eigenschaften des ggT aus:

fur b = 0
a
ggT (a b, b) fur a b
ggT (a, b) =

ggT (b, a)
fur a < b
Berechnen Sie die Werte 00 , 01 , 10 , 23 und 32 .
Losung zu 3.3
p u b l i c c l a s s GGT {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ]
int x , y ;
x = Integer . parse Int ( args [0])
y = Integer . parse Int ( args [1])
System . o u t . p r i n t l n ( Ggt : +
}

args ) {
;
;
ggt ( x , y ) ) ;

public s t a t i c int ggt ( int x , int y ) {


i f ( x < 0 | | y < 0) {
System . o u t . p r i n t l n ( Kein g g t b e r e c h n e t ) ;
r e t u r n 1;
}
else
i f ( y == 0 )
return x ;
else
if (x < y)
return ggt ( y , x ) ;
else
r e t u r n g g t ( xy , y ) ;
}
}

Das Programm solte folgende Werte liefern: 00 = 0, 01 = 0, 10 = 1, 23 = 8 und 32 = 9

4. 13

Felder

Aufgabe 4.1
Schreiben Sie ein Programm, das die schriftliche Addition zweier sehr groer (z.B. 50-stelliger) Zahlen simuliert.
Die beiden Zahlen sollen jeweils in einem Integer-Array dargestellt werden. Jedes Array-Element enthalt genau
eine Dezimalstelle.
Bedenken Sie, dass die Summe eine Stelle mehr haben kann.
Beispiel fur die Darstellung der 12-stelligen Zahl 401312570486 (401 Mrd. 312 Mio. . . .):
i n t [ ] l a n g Z a h l = new i n t [ 1 1 ] ;
langZahl [0] = 6;
langZahl [1] = 8;
langZahl [2] = 4;
langZahl [3] = 0;
langZahl [4] = 7;
langZahl [5] = 5;
langZahl [6] = 2;
langZahl [7] = 1;
langZahl [8] = 3;
langZahl [9] = 1;
langZahl [10] = 0;
langZahl [11] = 4;

Sie konnen den Zufallszahlengenerator benutzen, um die beiden 50-stelligen Summanden mit Werten zu belegen:
int l = 50;
i n t [ ] z a h l 1 = new i n t [ l ] ;
i n t [ ] z a h l 2 = new i n t [ l ] ;

/ / Anzahl der S t e l l e n
/ / 1 . Summand
/ / 2 . Summand

/ / d i e b e i d e n Summanden m i t z u f a e l l i g e n W er ten b e l e g e n
Random r = new j a v a . u t i l . Random ( ) ;
f o r ( i n t i = 0 ; i < l ; i ++) {
zahl1 [ i ] = r . n e xt I nt (10) ;
zahl2 [ i ] = r . n e xt I nt (10) ;
}

Losung zu 4.1
import j a v a . u t i l . ;
p u b l i c c l a s s L an g Z ah l {
p u b l i c s t a t i c i n t [ ] add ( i n t [ ] a , i n t [ ] b ) {
/ / V o r a u s s e t z u n g : a und b s i n d g l e i c h l a n g
i n t [ ] c = new i n t [ a . l e n g t h + 1 ] ; / / F e l d f u e r d a s E r g e b n i s
int i ;
// Schleifenzaehler
int s ;
/ / Summe d e r a k t u e l l b e r e c h n e t e n S t e l l e
i n t u e b e r t r a g = 0; / / Uebertrag fu er d ie n a ech s te S t e l l e
f o r ( i = 0 ; i < c . l e n g t h 1; i = i +1 ) {
s = a[ i ] + b[ i ];
c [ i ] = ( s + uebertrag ) % 10;
uebertrag = s / 10;
}
c [ c . l e n g t h 1] = u e b e r t r a g ;
return c ;
}
public s t a t i c void ausgeben ( S t r i n g s , i n t [ ] f e l d ) {
int i ;
System . o u t . p r i n t ( s ) ;
f o r ( i = f e l d . l e n g t h 1; i >= 0 ; i = i 1)
System . o u t . p r i n t ( f e l d [ i ] ) ;
System . o u t . p r i n t l n ( ) ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {

4. 14

int
int
int
int

anzS = 5 0 ;
[ ] z a h l 1 = new i n t [ anzS ] ;
[ ] z a h l 2 = new i n t [ anzS ] ;
[ ] zahl3 ;

//
//
//
//

Anzahl der S t e l l e n
1 . Summand
2 . Summand
Ergebnis

/ / d i e b e i d e n Summanden m i t z u f a e l l i g e n W er ten b e l e g e n
Random r = new j a v a . u t i l . Random ( ) ;
f o r ( i n t i = 0 ; i < anzS ; i ++) {
zahl1 [ i ] = r . n e xt In t (10) ;
zahl2 [ i ] = r . n e xt In t (10) ;
}
/ / E r g e b n i s b e r e c h n e n und a u s g e b e n
z a h l 3 = add ( z a h l 1 , z a h l 2 ) ;
a u s g e b e n ( 1 . Summand : , z a h l 1 ) ;
a u s g e b e n ( 2 . Summand : , z a h l 2 ) ;
a u s g e b e n ( Summe :
, zahl3 ) ;
}
}

Aufgabe 4.2
Schreiben Sie ein Programm, das das Minimum und das Maximum der Eintrage eines Feldes bestimmt.
a) Strukturieren Sie Ihr Programm durch Methoden. Sie sollten mindestens die folgenden Teilaufgaben in je einer
Methode realisieren:
Belegen des Feldes mit Zufallszahlen.
Ausgabe der Feldelemente auf dem Bildschirm.
Suchen des kleinsten Elementes im Feld.
Suchen des groten Elementes im Feld.

b) Andern Sie ihr Programm nun so ab, dass innerhalb einer Methode sowohl Minimum als auch Maximum
bestimmt werden und beide Werte an das Hauptprogramm zuruckgegeben werden.
Losung zu 4.2
import j a v a . u t i l . ;
p u b l i c c l a s s FeldMinMax {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
int
int
int
int

[ ] eingabe ;
/ / d a s F e l d m i t den E i n g a b e w e r t e n
l;
/ / Laenge d e s F e l d e s
min ;
/ / minimaler Eintrag
max ;
/ / m a xim a ler E i n t r a g

l = Integer . parse Int ( args [0]) ;


e i n g a b e = new i n t [ l ] ;
belegen ( eingabe ) ;
drucken ( eingabe ) ;
/ / fuer AufgabenTeil a )
min = minimum ( e i n g a b e ) ;
max = maximum ( e i n g a b e ) ;
System . o u t . p r i n t l n ( K l e i n s t e r Wert : + min ) ;
System . o u t . p r i n t l n ( G r o e s s t e r Wert : + max ) ;
/ / fuer Aufgabenteil b )
System . o u t . p r i n t l n ( K l e i n s t e r Wert : + minmax ( e i n g a b e ) [ 0 ] ) ;
System . o u t . p r i n t l n ( G r o e s s t e r Wert : + minmax ( e i n g a b e ) [ 1 ] ) ;
}
public s t a t i c void drucken ( i n t [ ] f e l d ) {
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
System . o u t . p r i n t ( f e l d [ i ] + ) ;
System . o u t . p r i n t l n ( ) ;
}

4. 15

public s t a t i c void belegen ( i n t [ ] f e l d ) {


/ / b e l e g t e i n I n t e g e r F e l d m i t Z u f a l l s z a h l e n z w i s c h e n 0 und 99
Random r = new Random ( ) ;
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
fe l d [ i ] = r . n e xt In t (100) ;
}
p u b l i c s t a t i c i n t minimum ( i n t [ ] f e l d ) {
i n t min = f e l d [ 0 ] ;
f o r ( i n t i = 1 ; i < f e l d . l e n g t h ; i ++)
i f ( f e l d [ i ] < min )
min = f e l d [ i ] ;
r e t u r n min ;
}
p u b l i c s t a t i c i n t maximum ( i n t [ ] f e l d ) {
i n t max = f e l d [ 0 ] ;
f o r ( i n t i = 1 ; i < f e l d . l e n g t h ; i ++)
i f ( f e l d [ i ] > max )
max = f e l d [ i ] ;
r e t u r n max ;
}

public
int
int
int
for

s t a t i c i n t [ ] minmax ( i n t [ ] f e l d ) {
[ ] m = new i n t [ 2 ] ;
min = f e l d [ 0 ] ;
max = f e l d [ 0 ] ;
( i n t i = 1 ; i < f e l d . l e n g t h ; i ++) {
i f ( f e l d [ i ] < min )
min = f e l d [ i ] ;
i f ( f e l d [ i ] > max )
max = f e l d [ i ] ;

}
m[ 0 ] = min ;
m[ 1 ] = max ;
r e t u r n m;
}
}

Aufgabe 4.3
In folgendem Programm wird eine Integer-Array zufallszahlender Lange 100 mit zufalligen Werten zwischen 0 und 9 belegt.
Definieren Sie eine Methode, die fur jede der Zahlen 0 bis 9 zahlt, wie oft sie in dem Feld zufallszahlen vorkommt
und diese Anzahlen in einem zweiten Array der Lange 10 zuruckgibt.
import j a v a . u t i l . ;
public cl as s Zu fa ll s Za e hl er {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i n t [ ] z u f a l l s z a h l e n = new i n t [ 1 0 0 ] ;
in t [ ] anzahl ;
belegen ( z u f a l l s z a h l e n ) ;
System . o u t . p r i n t l n ( z u f a e l l i g g ezo g en e n Z a h l e n : ) ;
drucken ( z u f a l l s z a h l e n ) ;
//
//
//
//

A u f r u f d e r Methode z a e h l e n ( P a r a m eter ? ) :
anzahl = z aehlen ( ?) ;
System . out . p r i n t l n ( H a e u f i g k e i t : ) ;
drucken ( anzahl ) ;

}
public s t a t i c void belegen ( i n t [ ] f e l d ) {
Random r = new Random ( ) ;
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
feld [ i ] = r . nextInt (10) ;
}

4. 16

public s t a t i c void drucken ( i n t [ ] f e l d ) {


f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
System . o u t . p r i n t ( f e l d [ i ] + ) ;
System . o u t . p r i n t l n ( ) ;
}
/ / D e f i n i t i o n d e r Methode z a e h l e n ( P a r a m eter ? )
}

Ein Beispielaufruf liefert folgendes Ergebnis:


> java ZufallsZaehler
zufaellig gezogene Zahlen:
2 2 0 4 8 9 6 0 9 7 4
9 4 5 8 3 6 0 0 0 4 8
3 2 4 8 0 9 7 3 3 9 0
4 9 5 8 8 6 0 3 9 3 2
Haeufigkeit:
15 2 11 13 10 6 11 7 10

2
4
2
7

2
6
3
9

1
6
5
0

0
9
5
4

9
2
3
7

3
3
8
2

4
0
7
6

15

Losung zu 4.3
import j a v a . u t i l . ;
public cl as s Zu fa ll s Za e hl er {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
i n t [ ] z u f a l l s z a h l e n = new i n t [ 1 0 0 ] ;
in t [ ] anzahl ;
belegen ( z u f a l l s z a h l e n ) ;
System . o u t . p r i n t l n ( z u f a e l l i g g e z o g e n e Z a h l e n : ) ;
drucken ( z u f a l l s z a h l e n ) ;
anzahl = zaehlen ( z u f a l l s z a h l e n ) ;
System . o u t . p r i n t l n ( H a e u f i g k e i t : ) ;
drucken ( anzahl ) ;
}
public s t a t i c void belegen ( i n t [ ] f e l d ) {
Random r = new Random ( ) ;
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
feld [ i ] = r . nextInt (10) ;
}
public s t a t i c void drucken ( i n t [ ] f e l d ) {
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++)
System . o u t . p r i n t ( f e l d [ i ] + ) ;
System . o u t . p r i n t l n ( ) ;
}
public s t a t i c int [ ] zaehlen ( int [ ] fe l d ) {
i n t [ ] e r g e b n i s = new i n t [ 1 0 ] ;
f o r ( i n t i = 0 ; i < e r g e b n i s . l e n g t h ; i ++)
ergebnis [ i ] = 0;
f o r ( i n t i = 0 ; i < f e l d . l e n g t h ; i ++) {
ergebnis [ feld [ i ]]++;
}
return er g eb n is ;
}
}

0
8
5
1

3
9
7
2

6
3
7
9

6
6
9
5

2
6
3
0

9
4
8
8

9
0
0
6

5. 17

OOP

Aufgabe 5.1
Eine Autovermietung vermietet PKW und LKW. Jedes Fahrzeug ist durch das KFZ-Kennzeichen, den KM-Stand
und die seit der letzten Inspektion geleisteten KM beschrieben. Bei LKW ist die Nutzlast ein weiteres Merkmal.
Zusatzlich gibt es eine Kennzeichnung, ob ein Fahrzeug zur Zeit vermietet ist.
Bei Ruckgabe eines Fahrzeuges wird aus der Mietdauer (in Tagen) der Rechnungsbetrag und aus der Zahl der
gefahrenen Kilometer der aktuelle KM-Stand ermittelt. Auerdem wird kontrolliert, ob eine Inspektion fallig ist.
Bei PKW wird alle 30000, bei LKW alle 20000 km eine Inspektion durchgefuhrt. Der Mietpreis betragt fur PKW
30 Euro pro Tag, fur LKW mit einer Nutzlast u ber 1800 kg 80 Euro pro Tag, fur kleinere LKW 50 Euro pro Tag.
PKW werden nach jeder Vermietung gewaschen.
a) Modellieren Sie diese Problemstellung durch geeignete Klassen und Methoden in Java. Falls fur eine Aktion
keine Details bekannt sind, lassen Sie den Methodenrumpf leer oder geben Sie eine passende Meldung auf den
Bildschirm aus.
b) Erweitern Sie das Beispiel: die Autovermietung mochte die Zahl der verfugbaren PKW und die der verfugbaren
LKW abrufen konnen.
Losung zu 5.1
Wir definieren eine Klasse KFZ mit zwei Unterklassen PKW und LKW. Desweiteren programmieren wir eine
ausfuhrbare Klasse Autovermietung, in deren main-Methode Objekte der PKW- und LKW-Klasse erzeugt
werden.
p u b l i c c l a s s KFZ {
S t r i n g Kennzeichen ;
i n t KMStand ;
i n t K M S eitI n s p ;
in t AbstandInsp ;
b o o lea n f r e i ;
int Preis ;
KFZ ( S t r i n g Kennz , i n t KM) {
K e n n z e i c h e n = Kennz ;
KMStand = KM;
K M S eitI n s p = KM;
f r e i = true ;
}
void vermieten ( ) {
if ( frei ) {
frei = false ;
System . o u t . p r i n t l n ( K e n n z e i c h e n + w i r d v e r m i e t e t ) ;
}
else
System . o u t . p r i n t l n ( K e n n z e i c h e n + i s t b e r e i t s v e r m i e t e t ) ;
}
v o i d z u r u e c k g e b e n ( i n t t a g e , i n t gefKM ) {
f r e i = true ;
KMStand = KMStand + gefKM ;
K M S eitI n s p = K M S eitI n s p + gefKM ;
System . o u t . p r i n t l n ( R e c h n u n g s b e t r a g : + P r e i s b e r e c h n u n g ( t a g e ) ) ;
i f ( K M S eitI n s p > A b s t a n d I n s p )
Inspektion () ;
}
void I n s p e k t i o n ( ) {
System . o u t . p r i n t l n ( I n s p e k t i o n d u r c h f u e h r e n ) ;
K M S eitI n s p = 0 ;
}
int Preisberechnung ( int t ) {
return t P r e i s ;
}
}

5. 18

p u b l i c c l a s s LKW e x t e n d s KFZ {
s t a t i c int verfuegbar = 0;
int Nutzlast ;

/ / n u r f u r T e i l b )

LKW ( S t r i n g Kennz , i n t KM, i n t l a s t ) {


s u p er ( Kennz , KM) ;
Nutzlast = last ;
AbstandInsp = 20000;
i f ( N u t z l a s t > 1800)
Pre is = 80;
else
Pre is = 50;
verfuegbar = verfuegbar + 1;
/ / Teil b)
}
/ / f u r T e i l b )
void vermieten ( ) {
if ( frei )
verfuegbar = verfuegbar 1;
s u p er . v e r m i e t e n ( ) ;
}
v o i d z u r u e c k g e b e n ( i n t t a g e , i n t gefKM ) {
s u p er . z u r u e c k g e b e n ( t a g e , gefKM ) ;
verfuegbar = verfuegbar + 1;
}
}

p u b l i c c l a s s PKW e x t e n d s KFZ {
s t a t i c i n t v e r f u e g b a r = 0 ; / / n u r f u r T e i l b )
PKW ( S t r i n g Kennz , i n t KM) {
s u p er ( Kennz , KM) ;
AbstandInsp = 30000;
Prei s = 30;
verfuegbar = verfuegbar + 1;
}

/ / Teil b)

v o i d z u r u e c k g e b e n ( i n t t a g e , i n t gefKM ) {
s u p er . z u r u e c k g e b e n ( t a g e , gefKM ) ;
waschen ( ) ;
/ / f u r T e i l b )
verfuegbar = verfuegbar + 1;
}
v o i d waschen ( ) {
System . o u t . p r i n t l n ( K e n n z e i c h e n + w i r d g ew as ch en ) ;
}
/ / f u r T e i l b )
void vermieten ( ) {
if ( frei )
verfuegbar = verfuegbar 1;
s u p er . v e r m i e t e n ( ) ;
}
}

public c l a s s Autovermietung {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) {
PKW p1 = new PKW( PKW 1 , 1 2 ) ;
PKW p2 = new PKW( PKW 2 , 0 ) ;
LKW l 1 = new LKW( LKW 1 , 1 9 0 0 0 , 1 5 0 0 ) ;
zeigeVerfuegbare () ;
p1 . v e r m i e t e n ( ) ;

5. 19

zeigeVerfuegbare ()
p1 . v e r m i e t e n ( ) ;
zeigeVerfuegbare ()
p1 . z u r u e c k g e b e n ( 2 ,
zeigeVerfuegbare ()
l1 . vermieten ( ) ;
zeigeVerfuegbare ()
l1 . zurueckgeben ( 3 ,
zeigeVerfuegbare ()
l1 . vermieten ( ) ;
zeigeVerfuegbare ()
l1 . zurueckgeben ( 1 ,
zeigeVerfuegbare ()

;
;
120) ;
;
;
1800) ;
;
;
100) ;
;

}
/ / nur f u e r T e i l b )
s t a t i c void zeigeV er f uegbar e ( ) {
System . o u t . p r i n t l n ( ) ;
System . o u t . p r i n t l n ( f r e i : + PKW. v e r f u e g b a r + PKW und +
LKW. v e r f u e g b a r + LKW ) ;
}
}

Das Programm liefert folgende Ausgabe


> java Autovermietung
frei: 2 PKW und 1 LKW
P-KW 1 wird vermietet
frei: 1 PKW und 1 LKW
P-KW 1 ist bereits vermietet
frei: 1 PKW und 1 LKW
Rechnung fuer P-KW 1: 60
P-KW 1 wird gewaschen
frei: 2 PKW und 1 LKW
L-KW 1 wird vermietet
frei: 2 PKW und 0 LKW
Rechnung fuer L-KW 1: 150
Inspektion durchfuehren
frei: 2 PKW und 1 LKW
L-KW 1 wird vermietet
frei: 2 PKW und 0 LKW
Rechnung fuer L-KW 1: 50
frei: 2 PKW und 1 LKW