fakult¨at f¨ur informatik

Werbung
TECHNISCHE UNIVERSITÄT MÜNCHEN
FAKULTÄT FÜR INFORMATIK
Lehrstuhl für Sprachen und Beschreibungsstrukturen
Einführung in die Informatik I
Prof. Dr. Helmut Seidl, M. Schwarz, A. Herz, Dr. M. Petter
WS 11/12
Übungsblatt 4
10.11.10
Abgabe: 21.11.10 (vor 12 Uhr)
Aufgabe 4.1 (P) Arrays verstehen
Diskutieren Sie, was in dem folgenden Programm passiert.
1 public c l a s s MeineArrays extends MiniJava {
2
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3
4
int [ ] e r s t e s A = { 1 , 2 , 3 , 4 } ;
5
write ( erstesA [ 1 ] ) ;
6
7
int [ ] z w e i t e s A = new int [ 7 ] ;
8
zweitesA [ 0 ] = 3 ;
9
int i =1;
10
while ( i <z w e i t e s A . l e n g t h ) {
11
z w e i t e s A [ i ] = i +3;
12
i ++;
13
}
14
15
fo r ( int j =0; j <z w e i t e s A . l e n g t h ; j ++) {
16
write ( zweitesA [ j ] ) ;
17
i ++;
18
}
19
20
write ( zweitesA [ i ] ) ;
21
22
zweitesA = erstesA ;
23
zweitesA [ 1 ] = 2 5 ;
24
write ( erstesA [ 1 ] ) ;
25
}
26 }
Lösungsvorschlag 4.1
Folgendes passiert in dem Programm:
4 Anlegen eines Arrays mit festem Inhalt
5 Ausgeben des Wertes an Position 1 → 2 (Die Positionen beginnen bei 0.)
7 Anlegen eines leeren Arrays der Länge 7
8 Füllen der Position 0 mit dem Wert 3
11 Füllen der i-ten Position mit i + 3
2
9-13 Das zweite Array ist [3, 4, 5, 6, 7, 8, 9]
15 For-Schleife durchläuft das Array
15-18 Schrittweises Ausgeben des Arrays
17 Variable i wird insgesamt um Länge von Array zweitesA hochgezählt
20 Laufzeitfehler! Position i existiert in Array zweitesA nicht. Es wird eine ArrayIndexOutOfBoundsException geworfen.
22 Die Referenz auf Array erstesA wird in Variable zweitesA kopiert.
23 Das Feld 1 des Arrays, auf das sich zweitesA bezieht, wird auf 25 gesetzt.
24 Durch Zeile 23 wurde auch diese Ausgabe beeinflusst, da erstesA seit Zeile 22 das
selbe Array referenziert wie zweitesA.
Aufgabe 4.2 (P) Minimum und Maximum
Schreiben Sie ein MiniJava-Programm namens MinMax.java, das in einem Array von ganzen Zahlen den kleinsten und den größten Wert findet. Das Programm soll sich wie folgt
verhalten:
• Zunächst fragt das Programm ab, wie viele Zahlen in das Array eingegeben werden
sollen.
• Dann werden die Zahlen eingegeben und in einem Array gespeichert.
• Anschließend wird das Array durchsucht und in einem Durchgang soll sowohl die
kleinste als auch die größte Zahl gefunden werden.
• Schließlich sollen die kleinste und die größte Zahl ausgegeben werden.
Lösungsvorschlag 4.2
public c l a s s MinMax extends MiniJava {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
// Anzahl d e r e i n z u g e b e n d e n Zahlen a b f r a g e n
int e i n g a b e n = r e a d I n t ( ”Wie v i e l e Zahlen m c h t e n S i e e i n g e b e n ? ”
);
i f ( eingaben < 1) {
return ;
}
// Array a n l e g e n
int [ ] z a h l e n = new int [ e i n g a b e n ] ;
// Array mit Zahlen f l l e n
int z a h l ;
int i = 0 ;
while ( i < e i n g a b e n ) {
z a h l = r e a d I n t ( ” B i t t e geben S i e d i e ”
+ ( i + 1 ) + ” . Zahl e i n . ”) ;
3
zahlen [ i ] = zahl ;
i ++;
}
// min und max b e r e c h n e n
int min = z a h l e n [ 0 ] ;
int max = z a h l e n [ 0 ] ;
i = 1;
while ( i < e i n g a b e n ) {
i f ( z a h l e n [ i ] < min ) {
min = z a h l e n [ i ] ;
}
i f ( z a h l e n [ i ] > max) {
max = z a h l e n [ i ] ;
}
i ++;
}
// Ausgeben
w r i t e ( ”Die k l e i n s t e Zahl war ” + min ) ;
w r i t e ( ”Die g r t e Zahl war ” + max) ;
}
}
Aufgabe 4.3 (P) Addition von Arrays
Schreiben Sie ein MiniJava-Programm namens Add.java,
9 5 1 5
welches zwei positive Zahlen einliest und diese in int- a1 :
Arrays a1 der Länge m und a2 der Länge n stellenweise ein- a2 : +
7 1 6
fügt. Ein Arrayelement soll hierbei nur die Ziffern 0, 1, . . . , 9
beinhalten. (ints können maximal 10 Dezimalstellen ha- a :
1 0 2 3 1
3
ben.) Anschließend werden die beiden Arrays addiert (wie
beim schriftlichen Addieren aus der Schule) und das Ergebnis dieser Addition wird in ein Array a3 der Länge max(m, n) + 1 abgespeichert. Dann soll das Ergebnisarray a3 mit Hilfe der
Methode java.util.Arrays.toString(a3 ) in einen String verwandelt und ausgegeben
werden.
Lösungsvorschlag 4.3
public c l a s s Add extends MiniJava {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
int i 1 = r e a d ( ) ;
int i 2 = r e a d ( ) ;
// 11 S t e l l e n r e i c h e n l o c k e r f u e r 32 b i t −i n t s
int [ ] a1 = new int [ 1 1 ] ;
int [ ] a2 = new int [ 1 1 ] ;
// 12 S t e l l e n wegen U e b e r t r a g !
int [ ] a3 = new int [ 1 2 ] ;
4
// Z u e r s t Eingabe i n Arrays v e r w a n d e l n !
// dazu gehen w i r a l l e 10 er−S t e l l e n durch :
int i =0;
while ( i 1 >0 | | i 2 >0){
a1 [ i ]= i 1 %10;
a2 [ i ]= i 2 %10;
i 1=i 1 / 1 0 ;
i 2=i 2 / 1 0 ;
i ++;
}
int u e b e r t r a g =0;
fo r ( int j =0; j <11; j ++){
// S t e l l e n und den l e t z t e n U e b e r t r a g aufsummieren
int summe = a1 [ j ]+ a2 [ j ]+ u e b e r t r a g ;
// a l l e 10 e r i n den U e b e r t r a g
u e b e r t r a g=summe / 1 0 ;
// a l l e 1 e r i n d i e r i c h t i g e S t e l l e
a3 [ j ]= summe%10;
}
// l e t z t e n U e b e r t r a g n i c h t v e r g e s s e n
a3 [ 1 1 ] = u e b e r t r a g ;
// K o n v e r t i e r u n g und Ausgabe d e r Menge r e s u l t
S t r i n g e r g e b n i s = j a v a . u t i l . Arrays . t o S t r i n g ( a3 ) ;
write ( ergebnis ) ;
}
}
Aufgabe 4.4 [4 Punkte] (H) Sieb des Eratosthenes
Folgendes Verfahren zur Primzahlen-Gewinnung ist als Sieb des Eratosthenes bekannt:
Aus der Menge der natürlichen Zahlen von 2 bis n werden alle Nicht-Primzahlen gestrichen.
Beginne mit der Zahl 2 und streiche alle echten Vielfachen von 2. Streiche nun sukzessiv alle
echten Vielfachen der jeweils nächsthöheren noch nicht gestrichenen Zahl. Nach Streichung
aller Vielfachen enthält die Restmenge nur noch Primzahlen.
Implementieren Sie das oben beschriebene Verfahren in Java mit Hilfe eines Arrays. Ihr
Programm soll nach Festlegung einer Obergrenze durch den Benutzer alle Primzahlen bis
zu dieser Grenze bestimmen und ausgeben.
Lösungsvorschlag 4.4
public c l a s s E r a t o s t h e n e s extends MiniJava {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
// Eingabe
int n = r e a d ( ) ;
i f (n < 0) {
// f e h l e r h a f t e Eingabe
w r i t e ( ”Nur p o s i t i v e Eingaben e r l a u b t . ”) ;
} else {
// k o r r e k t e Eingabe ; Berechnung kann e r f o l g e n
5
// S i e b a n l e g e n
boolean prime [ ] = new boolean [ n + 1 ] ;
f o r ( int i = 2 ; i < prime . l e n g t h ; i ++)
prime [ i ] = true ;
// Primzahlen b e r e c h n e n
f o r ( int i = 2 ; i < prime . l e n g t h ; i ++) {
i f ( prime [ i ] ) {
// Primza hl a u s g e b e n
System . out . p r i n t l n ( i ) ;
// a l l e V i e l f a c h e n s t r e i c h e n
f o r ( int j = i ∗ i ; j < prime . l e n g t h ; j = j + i ) {
prime [ j ] = f a l s e ;
}
}
}
}
}
}
Mögliche Optimierungen:
• Nur ungerade Zahlen berücksichtigen
• Berechnung bis zur Wurzel der oberen Grenze ist ausreichend
Aufgabe 4.5 [6+2 Punkte] (H) Mustererkennung
a) Schreiben Sie ein Programm namens Muster.java, das eine aus 0 und 1 Symbolen
bestehende Folge mit benutzerdefinierter Länge zufällig generiert und darin die längste Teilfolge bestehend ausschließlich aus 0 Symbolen findet. (Hinweis: Eine binäre
Zahl (0 oder 1) kann zufällig mit dem Ausdruck (int)(Math.random()*2) generiert
werden) Geben sie die Startposition und die Länge der gefunden Teilfolge aus.
b) Ergänzen Sie das Programm Muster.java so, dass die längste Folge von 0 Symbolen
in einem aus 0 und 1 Symbolen bestehendes zweidimensionales Array gefunden wird.
Erfragen sei die Größe vom Benutzer und generieren sie die Symbole zufällig. Geben
sie die Startkoordinaten, die Richtung (waagerecht, senkrecht, diagonal) und die Länge
der gefundenen Folge aus.
(Bonus) Ergänzen Sie das Programm Muster.java, so, dass in dem zweidimensionalen Array auch das größte Rechteck bestehend nur aus 0 Symbolen (d.h. auch die Fläche
besteht nur aus /tt 0en) gefunden wird. Geben sie die Startkoordinaten und die Grösse des gefundenen Rechtecks aus.
Lösungsvorschlag 4.5
public c l a s s MusterErkennung extends MiniJava {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
int symbol = 0 ;
6
// T e i l a u f g a b e a )
int n = r e a d ( ”Geben S i e d i e Laenge d e r F o l g e e i n : ”) ;
int [ ] s e q u e n c e = new int [ n ] ;
fo r ( int j = 0 ; j < n ; j ++) { // g e n e r a t e s y m b o l s
s e q u e n c e [ j ] = ( int ) ( Math . random ( ) + 0 . 5 ) ;
}
fo r ( int i = 0 ; i < s e q u e n c e . l e n g t h ; i ++) { // p r i n t
System . out . p r i n t ( s e q u e n c e [ i ] ) ;
}
System . out . p r i n t l n ( ) ;
int p = 0 ;
int max = 0 , posmax = 0 , pos = 0 ;
while ( p < s e q u e n c e . l e n g t h ) {
// u e b e r s p r i n g e unpassende Z e i c h e n
while ( p < s e q u e n c e . l e n g t h && s e q u e n c e [ p ] != symbol ) {
p++;
}
// merke S t a r t p o s i t i o n d e r Sequenz
pos = p ;
// s u c h e Ende d e r Sequenz
while ( p < s e q u e n c e . l e n g t h && s e q u e n c e [ p ] == symbol ) {
p++;
}
// f a l l s Sequenz l a e n g e r a l s b i s h e r i g e s Maximum , s e t z e
neues Maximum
i f ( p > pos && p − pos > max) {
posmax = pos ;
max = p − pos ;
}
}
i f (max > 0 ) { // Ausgabe d e s e r g e b n i s s e s
System . out . p r i n t l n ( ”Maximal s e q u e n c e s t a r t s a t ” + posmax +
” and has l e n g t h ”
+ max + ” . ”) ;
} else {
System . out . p r i n t l n ( ”No symbol ” + symbol + ” found . ”) ;
}
// T e i l a u f g a b e b )
int h = r e a d ( ”Geben S i e d i e Hoehe e i n : ”) ;
int b = r e a d ( ”Geben S i e d i e B r e i t e e i n : ”) ;
int [ ] [ ] s u r f a c e = new int [ h ] [ b ] ;
fo r ( int i = 0 ; i < h ; i ++) { // g e n e r a t e s y m b o l s
f o r ( int j = 0 ; j < b ; j ++) {
s u r f a c e [ i ] [ j ] = ( int ) ( Math . random ( ) + 0 . 5 ) ;
}
}
// o der f e s t e Werte zum Testen :
// i n t [ ] [ ] s u r f a c e =
{{1 ,0 ,0 ,1 ,1 ,1} ,{0 ,0 ,0 ,0 ,0 ,0} ,{0 ,1 ,0 ,0 ,0 ,1} ,{0 ,1 ,0 ,0 ,0 ,0} ,{1 ,1 ,1 ,0 ,0 ,1}
h=6; b =6;
// i n t [ ] [ ] { { 1 , 1 , 0 } , { 0 , 0 , 1 } , { 0 , 0 , 0 } } ; h = 3 ; b =3;
fo r ( int j = 0 ; j < s u r f a c e . l e n g t h ; j ++) { // p r i n t
f o r ( int i = 0 ; i < s u r f a c e [ 0 ] . l e n g t h ; i ++) {
System . out . p r i n t ( s u r f a c e [ j ] [ i ] ) ;
7
}
System . out . p r i n t l n ( ) ;
}
int s t e p , maxline =−1, maxx=−1, maxy=−1;
S t r i n g d i r = ”” ;
fo r ( int j = 0 ; j < h ; j ++) { // i t e r a t e o v e r l i n e s
f o r ( int i = 0 ; i < b ; i ++) // i t e r a t e o v e r columns
{
i f ( s u r f a c e [ j ] [ i ] == symbol ) {
// s t a r t l o o k i n g f o r l i n e s from t h e c u r r e n t p o i n t
step = 0;
while ( s t e p+i < b && s u r f a c e [ j ] [ s t e p+i ] == symbol )
{ // w a a a g e r e c h t
s t e p ++;
}
i f ( s t e p > maxline ) {
maxline = s t e p ;
maxx = i ;
maxy = j ;
dir = ”horizontally ”;
}
step = 0;
while ( s t e p+j < h && s u r f a c e [ s t e p+j ] [ i ] == symbol )
{ // s e n k r e c h t
s t e p ++;
}
i f ( s t e p > maxline ) {
maxline = s t e p ;
maxx = i ;
maxy = j ;
dir = ”vertically ”;
}
step = 0;
while ( s t e p+i < b && s t e p+j < h && s u r f a c e [ s t e p+j ] [
s t e p+i ] == symbol ) { // d i a g o n a l von l i n k s oben
nach r e c h t s unten
s t e p ++;
}
i f ( s t e p > maxline ) {
maxline = s t e p ;
maxx = i ;
maxy = j ;
d i r = ” d i a g o n a l l y ( down ) ” ;
}
step = 0;
while ( i −s t e p >=0 && s t e p+j < h && s u r f a c e [ s t e p+j
] [ i −s t e p ] == symbol ) { // d i a g o n a l von r e c h t s
oben nach l i n k s unten
s t e p ++;
}
i f ( s t e p > maxline ) {
maxline = s t e p ;
maxx = i ;
maxy = j ;
d i r = ” d i a g o n a l l y ( up ) ” ;
}
8
}
}
}
System . out . p r i n t l n ( ”L ongest l i n e s t a r t s a t ( ” + maxx + ” , ” +
maxy + ”) , g o e s ” + d i r + ” and has l e n g h t ” + maxline + ” .
”) ; // E r g e b n i s a u s g a b e
// Bonusaufgabe :
// I d e e n : Bestimme f u e r j e d e P o s i t i o n ( n ,m) das maximale
Rechteck , das b e i ( n ,m) b e g i n n t .
// Das g r o e s s t e d i e s e r Rechecke i s t dann das g r o e s s t e d e s
gesamten F e l d e s .
int x , y , xMax = −1, yMax = −1, iMax = −1, jMax = −1;
int surfMax = 0 , s u r f ;
int i 1 ;
fo r ( int j = 0 ; j < h ; j ++) { // i t e r a t e o v e r l i n e s
f o r ( int i = 0 ; i < b ; i ++) // i t e r a t e o v e r coulmns
{
i f ( s u r f a c e [ j ] [ i ] == symbol ) {
// s t a r t l o o k i n g f o r r e c t a n g l e s from t h e c u r r e n t
point
x = i;
while ( x < b && s u r f a c e [ j ] [ x ] == symbol ) {
// i t e r a t e o v e r t h e p o s s i b l e l e n g t h s (
horizontally )
y = j + 1;
while ( y < h ) { // i t e r a t e o v e r p o s s i b l e b r e a d t h s
( vertically )
i1 = i ;
// c h e c k i f t h e r e a r e as much s y m b o l s on t h e
current l i n e
// as t h e c u r r e n t l e n g t h
while ( i 1 <= x && s u r f a c e [ y ] [ i 1 ] == symbol )
{
i 1 ++;
}
i f ( i 1 == x + 1 ) // yes , t h e r e a r e ; t r y t h e
n e x t row
{
y++;
} e l s e //no , t h e r e aren ’ t ; i t ’ s not a
rectangle
{
break ;
}
}
s u r f = ( x − i + 1 ) ∗ ( y − j ) ; // t h e c u r r e n t
surface
i f ( s u r f > surfMax ) // a new maximum ;
// remember t h e upper l e f t and l o w e r r i g h t
corners
{
surfMax = s u r f ;
xMax = x ;
yMax = y − 1 ;
9
iMax = i ;
jMax = j ;
}
x++;
}
}
}
}
System . out . p r i n t l n ( ” L a r g e s t r e c t a n g l e s t a r t s a t ( ” + iMax + ” , ”
+ jMax + ”) , ends a t ( ” + xMax + ” , ” + yMax + ”) ”
+ ” and has s u r f a c e ” + surfMax + ” . ”) ;
}
}
Herunterladen