C++ - Kontrollstrukturen – Teil 2 - fbi.h

Werbung
FB Informatik
Prof. Dr. R.Nitsch
C++ - Kontrollstrukturen – Teil 2
Reiner Nitsch
℡ 8417
[email protected]
Schleife und Verzweigung kombiniert
FB Informatik
Prof. Dr. R.Nitsch
Wichtiger Baustein vieler Algorithmen!
SV initialisieren
while(B1)
if(B2)
w
f
V1
V2
Beispiel: Ägyptische Multiplikation für natürliche Zahlen
⎧ b
⎪⎪2ai 2
aib = ⎨
⎪2aib + a
⎪⎩ 2
SV Richtung
Ziel verändern
falls b gerade
falls b ungerade
Ganzzahldivision!
Erklärung: a = 20, b = 23
a • b = 2a • b/2 +
a
20 • 23 = 40 • 11 +
1 • 20
40 • 11 = 80 •
5 +
1 • 40
80 • 5 = 160 •
2 +
1 • 80
160 • 2 = 320 •
1 +
0 • 160
320 • 1 = 640 •
0 +
1 • 320
Binärdarstellung von b
101112 = 2310
2010 • 101112 = 20 •(1 •24 + 0 •23 + 1 •22 + 1 •21 + 1 •20 )
=
320 + 0 •160 + 1 •80 + 1 •40 + 1 •20
= 460
→ 20 • 23 = 460
17.05.2008
C++ Kontrollstrukturen - Teil 2
2
Ägyptische Multiplikation in C++
FB Informatik
Prof. Dr. R.Nitsch
int multiply( int a , int b ) {
Produkt = 0
assert( a>0 && b>0 );
int product = 0;
solange b > 0
while ( b > 0 ) {
b ungerade?
if ( b%2 == 1 ) // ist b ungerade
ja
nein
product += a;
Produkt um
else
a erhöhen
;
a verdoppeln
a *= 2;
b /= 2;
b halbieren
} // while (b>0)
return product;
}
Alternative Realisierung mit Bitmanipulationen
• Test auf "b ungerade" durch Bittest
→ 101112
b = 2310
testmuster
→ 000012 = 110
b & testmuster → 00001
• Verdopplung:
• Halbierung:
a = 2010 = 000101002
b = 2310 = 000101112
2a = 4010 = 00101000 2
b/2 = 1110 = 00010112
0
17.05.2008
C++ Kontrollstrukturen - Teil 2
3
Ägyptische Multiplikation in C++
FB Informatik
Prof. Dr. R.Nitsch
int multiply( int a , int b ) {
int product = 0;
while ( b>0 ) {
if ( b&1 ) // ist b ungerade
product += a;
else
;
} // while (b>0)
return product;
}
17.05.2008
C++ Kontrollstrukturen - Teil 2
4
Rekursion
FB Informatik
Prof. Dr. R.Nitsch
• Rekursive Funktionen
– rufen sich wiederholt selbst auf
– tun dies, um jeweils ein kleineres Problem zu lösen
– enden erst dann ohne erneuten Selbstaufruf, wenn das Problem so klein ist, dass es gelöst
werden kann (→ base case).
Beispiel: Dreieckszahlen
d0 = 0
d1 = 0 + 1
d2 = 0 + 1 + 2
d3 = 0 + 1 + 2 + 3
n
n ( n + 1)
k =0
2
dn = ∑ k =
Iterative Lösung:
d0
x
d1
x
x x
d2
x
x x
x x x
d3
x
x x
x x x
x x x x
d4
x
x
x
x
x
x
x x
x x x
x x x x
d5
int triangleNumber ( int n ) {
assert(n>=0);
int result = 0;
assert(result == n*(n+1)/2 );
return result ;
}
17.05.2008
C++ Kontrollstrukturen - Teil 2
5
Rekursive Berechnung der Dreieckszahlen
Rekursive Definition
der Dreickzahlen:
x
x
x
x
x
dn = n + Rest
= n + dn-1
x
x x
x x x
x x x x
FB Informatik
Prof. Dr. R.Nitsch
int triangleNumber( int n ) {
assert( n>=0 );
d5 = 5 + Rest
}
5 + d4
Aufruf in main:
Rekursion wird durch das Konzept der lokalen
cout << triangleNumber(3);
Objekte ermöglicht: Jeder Aufruf erzeugt
einen neuen Satz aller lokalen Objekte auf
dem Stack!
n
Rückgabewert
1
9
3
3+3 = 6
2
8
2
2+1 = 3
3
7
1
0+1 = 1
4
6
0
5
17.05.2008
0
Rücksprungadresse
n=3
Rückgabewert
Rücksprungadresse
n=2
Rückgabewert
Rücksprungadresse
n=1
Rückgabewert
Rücksprungadresse
n=0
Rückgabewert
C++ Kontrollstrukturen - Teil 2
Vorsicht bei globalen
Variablen in rekursiven
Funktionen!
6
Rekursive Berechnung von n!
Iterative Definition
⎧1
n! = ⎨
⎩1⋅ 2 ⋅ ... ⋅ n
für n = 0
für n>0
FB Informatik
Prof. Dr. R.Nitsch
// Rekursive Lösung
long factorial ( int n ) {
assert ( n>=0 );
Rekursive Definition
17.05.2008
C++ Kontrollstrukturen - Teil 2
7
Noch ein Beispiel
FB Informatik
Prof. Dr. R.Nitsch
Invertieren einer beliebig langen Zeichenkette
void reverseString () {
char c;
cin >> c;
if ( c == '\n' )
return;
else {
reverseString ();
cout << c;
}
}
17.05.2008
C++ Kontrollstrukturen - Teil 2
8
Rekursive Berechnung von Fibonacci-Zahlen
Definition der Fibonacci Zahlen
F(n) =
1
1
F(n-1) + F(n-2)
für n = 0
für n = 1
für n > 1
Anwendung: Wachstumssimulation von Populationen
Erklärung: Hasenpopulation
h: Häschenpaar; 1 Monat Reifezeit
H: Schwangere Häsin; 1 Monat Tragezeit)
FB Informatik
Prof. Dr. R.Nitsch
Rekursive Realisierung in C++
long Fibonacci( int n ) {
assert (n>=0);
}
Iterative Realisierung in C++
long Fibonacci ( int n ) {
assert (n>=0);
Monat Population
long Fn, Fn_1(1), Fn_2(1);
0
h
if (n<2)
1
H
return 1;
2
Hh
F(n-2)
else
3
HHh
F(n-1)
while (n>1) {
F(n) = F(n-1) + F(n-2)
4
HHHhh
Fn = Fn_1 + Fn_2
5
HHHHHhhh
Fn_2 = Fn_1;
6
HHHHHHhhhhh
Fn_1 = Fn;
n--;
}
return 1;
9
17.05.2008
C++ Kontrollstrukturen - Teil 2 }
Türme von Hanoi - Problembeschreibung
17.05.2008
A
B
C
Subturm
Aufgabe: Turm aus 100 Scheiben umsetzen
• 2 Ablagestellen
• immer nur eine Scheibe transportieren
• Es darf keine größere auf einer kleineren
Scheibe liegen
• Turm von A nach C unter Zuhilfenahme von
B
Algorithmischer Kern
1. Turm außer unterster Scheibe (Subturm)
transportieren von A nach B (kleineres
Problem)
2. unterste Scheibe transportieren von A
nach B (base case)
3. Subturm von C nach B transportieren
(kleineres Problem)
FB Informatik
Prof. Dr. R.Nitsch
C++ Kontrollstrukturen - Teil 2
10
Türme von Hanoi - Implementation
FB Informatik
Prof. Dr. R.Nitsch
void move( int amount, char from, char to, char hilfe ) {
static int width(-5); //statische Variable mit Gültigkeitsbereich Programm
width += 5;
cout << endl;
cout << string( width, ' ' )
<< "Mein Auftrag ist: " << amount << " Scheibe(n) "
<< "von "
<< from
<< " nach " << to << endl;
if ( amount == 1 ) // Base Case (realer Transport)
cout << string( width, ' ' ) << "Ächz…Schwitz: "
//Anwendung
<< " Scheibe Nr. " << amount
void main(){
<< "von "
<< from
move( 3,'A','C','B' );
<< " nach " << to << endl;
cout << endl;
else { // Unteraufträge (virtueller Transport)
}
// Subturm zur Hilfsposition
move( amount-1, from, help, to );
//unterste Scheibe zur Zielposition 'nach' (realer Transport)
cout << string( width,' ') << "Ächz…Schwitz: "
<< Scheibe Nr. " << amount
<< " von "
<< from
<< " nach " << to << endl;
// Subturm von Hilfsposition 'Hilfe' zur Zielposition 'nach'
move( amount-1, help, to, from );
width -=5;
} //else
}
17.05.2008
C++ Kontrollstrukturen - Teil 2
11
Türme von Hanoi - Ausgabe
FB Informatik
Prof. Dr. R.Nitsch
A
B
C
Mein Auftrag ist: 3 Scheibe(n) von A nach C
Mein Auftrag ist: 2 Scheibe(n) von A nach B
Mein Auftrag ist: 1 Scheibe(n) von A nach C
Ich transportiere: 1 Scheibe(n) von A nach C
Ich transportiere: 1 Scheibe von A nach B
Mein Auftrag ist: 1 Scheibe(n) von C nach B
Ich transportiere: 1 Scheibe(n) von C nach B
Ich transportiere: 1 Scheibe von A nach C
Mein Auftrag ist: 2 Scheibe(n) von B nach C
Mein Auftrag ist: 1 Scheibe(n) von B nach A
Ich transportiere: 1 Scheibe(n) von B nach A
Ich transportiere: 1 Scheibe von B nach C
Mein Auftrag ist: 1 Scheibe(n) von A nach C
Ich transportiere: 1 Scheibe(n) von A nach C
Press any key to continue
17.05.2008
C++ Kontrollstrukturen - Teil 2
12
Türme von Hanoi - Komplexität
FB Informatik
Prof. Dr. R.Nitsch
Turm hat laut Überlieferung insgesamt n Scheiben
1. Mönch
Scheibe n
1 mal transportieren
2. Mönch
Scheibe n-1
2 mal transportieren
3. Mönch
Scheibe n-2
4 mal transportieren
4. Mönch
Scheibe n-3
8 mal transportieren
i. Mönch
Scheibe n+1-i
2i-1 mal transportieren
n. Mönch
Scheibe 1
2n-1 mal transportieren
Summe: T =
n
∑2
i −1
= 2n − 1
i =1
Weltuntergang, wenn alle 100 Scheiben transportiert sind?
Annahme: Scheiben werden im Sekundentakt transportiert
In wieviel Jahren ist dann der Weltuntergang?
17.05.2008
C++ Kontrollstrukturen - Teil 2
13
Herunterladen