Algorithmen und Datenstrukturen (für ET/IT) - CAMP-TUM

Werbung
Algorithmen und Datenstrukturen (für ET/IT)
Wintersemester 2012/13
Dr. Tobias Lasser
Computer Aided Medical Procedures
Technische Universität München
Organisatorisches
Nächste Woche keine Vorlesung!
Es finden nächste Woche keine Vorlesungen statt!
• Mittwoch, 31. Oktober 2012: FVV
(Fachschaftsvollversammlung)
• Donnerstag, 1. November 2012: Feiertag (Allerheiligen)
Der Übungsbetrieb (Zentralübung, Montag 29. Oktober 2012,
sowie die Fragestunden, Freitag, 2. November 2012) findet statt!
2
Wiederholung letzte Vorlesung
Ganze Zahlen in C, C++
Ganze Zahlen in C, C++
• 8 Bits: unsigned char {0, . . . , 255}
signed char {−128, . . . , 127}
• 16 Bits: unsigned short {0, . . . , 65535}
signed short {−32768, . . . , 32767}
• 32 Bits: unsigned long {0, . . . , 232 − 1}
signed long {−232 , . . . , 232 − 1}
• 64 Bits: unsigned long long {0, . . . , 264 − 1}
signed long long {−264 , . . . , 264 − 1}
• signed kann weggelassen werden (ausser bei char!)
• unsigned int und signed int sind je nach System 16, 32
oder 64 Bit
11
3
Wiederholung letzte Vorlesung
Floating Point Zahlen II
1 Bit
11 Bit
52 Bit
64 Bit double
1 Bit
8 Bit
23 Bit
32 Bit float
V
Exponent E
Mantisse M
Ganze Zahlen in C, C++
• wissenschaftliche Darstellung mit Basis 2
Ganze Zahlen in C, C++
f = (−1)V · (1 + M) · 2E −bias
• 8 Bits: unsigned char {0, . . . , 255}
signed• char
{−128,Bit
. . .V, 127}
Vorzeichen
• 16 Bits: unsigned
short M
{0,hat
. . . immer
, 65535}
• Mantisse
die Form 1.abc, also wird erste Stelle
signed weggelassen
short {−32768,
. . . , 32767}
( hidden
bit“)
”
• 32 Bits: unsigned
long {0,
. . , 232
− 1}
• Exponent
E .wird
vorzeichenlos
abgespeichert, verschoben um
signed bias
long {−232 , . . . , 232 − 1}
64 127,
bei 32long
bit float:
• 64 Bits: unsigned •long
{0, . .bias
. , 2=
− 1}bei 64 bit float: bias = 1023
signed long long {−264 , . . . , 264 − 1}
15
• signed kann weggelassen werden (ausser bei char!)
• unsigned int und signed int sind je nach System 16, 32
oder 64 Bit
11
3
Wiederholung letzte Vorlesung
Logische Werte und Verknüpfungen
Grundrechenarten“ mit logischen Werten:
”
Floating Point
• Konjunktion: ∧ : B × B → B
• ähnlich zu Multiplikation bei Zahlen
Zahlen• IIauch bezeichnet als UND bzw. AND
1 Bit
11 Bit
1 Bit
8 Bit
•
V
Ganze Zahlen in C, C++
52 Bit
Disjunktion: ∨ : 23BBit× B → B
64 Bit double
32 Bit float
Exponent E • ähnlich zu
Mantisse
M bei Zahlen
Addition
• auch bezeichnet als ODER bzw. OR
• wissenschaftliche Darstellung mit Basis 2
• Negation: ¬ : B → B
V
f •= auch
(−1)bezeichnet
· (1 + M)
2E −bias bzw. NOT
als· NICHT
• 8 Bits: unsigned char {0, . . . , 255}
Wahrheitstabelle:
a
0
0
1
1
b
0
1
0
1
a∧b
0
0
0
1
a
0
0
1
1
b
0
1
0
1
a∨b
0
1
1
1
a
0
1
¬a
1
0
Ganze Zahlen in C, C++
signed• char
{−128,Bit
. . .V, 127}
Vorzeichen
• 16 Bits: unsigned
short M
{0,hat
. . . immer
, 65535}
• Mantisse
die Form 1.abc, also wird erste Stelle
signed weggelassen
short {−32768,
. . . , 32767}
( hidden
bit“)
”
21
• 32 Bits: unsigned
long {0,
. . , 232
− 1}
• Exponent
E .wird
vorzeichenlos
abgespeichert, verschoben um
signed bias
long {−232 , . . . , 232 − 1}
64 127,
bei 32long
bit float:
• 64 Bits: unsigned •long
{0, . .bias
. , 2=
− 1}bei 64 bit float: bias = 1023
signed long long {−264 , . . . , 264 − 1}
15
• signed kann weggelassen werden (ausser bei char!)
• unsigned int und signed int sind je nach System 16, 32
oder 64 Bit
11
3
Wiederholung letzte Vorlesung
Logische Werte und Verknüpfungen
Grundrechenarten“ mit logischen Werten:
”
b
0
1
0
1
a∧b
0
0
0
1
• logische Variablen: bool a,b; a b
Disjunktion: ∨ : 23BBit× B → B 32 Bit float
• logische
Werte: true und false
0 0
Exponent E • ähnlich zu
Mantisse
M bei Zahlen
Addition
1
0
1
a∨b
0
1
1
1
a
0
1
¬a
1
0
Floating Point
1 Bit
1 Bit
V
Ganze Zahlen in C, C++
• Konjunktion: ∧ : B × B → B
• ähnlich zu Multiplikation bei Zahlen
Zahlen• IIauch Logische
Ausdrücke
in C,
bezeichnet als
UND bzw. AND
Wahrheitstabelle:
11 Bit
52 Bit
64 Bit double
a
0
C++ 0
1
1
8 Bit
•
• auch bezeichnet
als ODER
bzw. !a
OR
• NOT
Operator:
• AND Operator: a && b
• wissenschaftliche Darstellung mit Basis 2
• OR Operator: a || b
• Negation: ¬ : B → B
V
f •= auch
(−1)bezeichnet
· (1 + M)
2E −bias bzw. NOT
als· NICHT
• 8 Bits: unsigned char {0, . . . , 255}
Beispiele:
0
1
1
Ganze Zahlen in C, C++
signed• char
{−128,Bit
. . .V, 127}
Vorzeichen
• ( (2 == 2) && (3 > 1) )
• 16 Bits: unsigned
short M
{0,hat
. . . immer
, 65535}
ergibt (true
&&erste
false),
• Mantisse
die Form 1.abc,
also wird
Stellealso false
signed weggelassen
short {−32768,
.
.
.
,
32767}
( hidden bit“)
• ( !(2 == 2) || (3 < 1) )
” 32
• 32 Bits: unsigned
long {0,
. . , 2vorzeichenlos
− 1}
ergibt (falseverschoben
|| true),
• Exponent
E .wird
abgespeichert,
umalso true
32
21
32
signed bias
long {−2 , . . . , 2 − 1}
• Kurzform für !(2 == 2) ist (2 != 2)
64 127,
bei 32long
bit float:
• 64 Bits: unsigned •long
{0, . .bias
. , 2=
− 1}bei 64 bit float: bias = 1023
signed long long {−264 , . . . , 264 − 1}
15
27
• signed kann weggelassen werden (ausser bei char!)
• unsigned int und signed int sind je nach System 16, 32
oder 64 Bit
11
3
Programm heute
1 Einführung
2 Mathematische Grundlagen
Mengen
Abbildungen
Zahldarstellung
Boolesche Logik
3 Elementare Datenstrukturen
Zeichenfolgen
Felder
4
Definition Datenstruktur
Definition Datenstruktur (nach Prof. Eckert)
Eine Datenstruktur ist eine
• logische Anordnung von Datenobjekten,
• die Informationen repräsentieren,
• den Zugriff auf die repräsentierte Information über
Operationen auf Daten ermöglichen und
• die Information verwalten.
Zwei Hauptbestandteile:
• Datenobjekte
• z.B. definiert über primitive Datentypen
• Operationen auf den Objekten
• z.B. definiert als Funktionen
5
Primitive Datentypen in C, C++
• Natürliche Zahlen, z.B. unsigned short, unsigned long
• Wertebereich: bei n Bit von 0 bis 2n − 1
• Operationen: +, -, *, /, %, <, ==, !=, >
• Ganze Zahlen, z.B. int, long
• Wertebereich: bei n Bit von −2n−1 bis 2n−1 − 1
• Operationen: +, -, *, /, %, <, ==, !=, >
• Floating Point Zahlen, z.B. double, float
• Wertebereich: abhängig von Größe
• Operationen: +, -, *, /, <, ==, !=, >
• Logische Werte, bool
• Wertebereich: true, false
• Operationen: &&, ||, !, ==, !=
Was ist mit Zeichen und Zeichenfolgen?
6
Bits und Bytes
Bit 7
Bit 0
1 Byte = 8 Bit
Bytes als Maßeinheit für Speichergrössen:
• 210 Bytes = 1024 Bytes = 1 kB, ein kilo Byte (großes B)
• 220 Bytes = 1 MB, ein Mega Byte
• 230 Bytes = 1 GB, ein Giga Byte
• 240 Bytes = 1 TB, ein Tera Byte
• 250 Bytes = 1 PB, ein Peta Byte
• 260 Bytes = 1 EB, ein Exa Byte
7
Bits und Bytes
Bit 7
Bit 0
1 Byte = 8 Bit
Bytes als Maßeinheit für Speichergrössen:
• 210 Bytes = 1024 Bytes = 1 kB, ein kilo Byte (großes B)
• 220 Bytes = 1 MB, ein Mega Byte
• 230 Bytes = 1 GB, ein Giga Byte
• 240 Bytes = 1 TB, ein Tera Byte
• 250 Bytes = 1 PB, ein Peta Byte
• 260 Bytes = 1 EB, ein Exa Byte
Hinweis: auch Bits werden als Maßangabe verwendet, z.B. 16 Mbit
oder 16 Mb (kleines b).
7
Bytes und ASCII
Interpretation eines Bytes als Zeichen (anstatt Zahlen)
−→ z.B. ASCII Code
7 Bit ASCII Code:
Code ..0 ..1
0..
1..
2..
3..
4..
5..
6..
7..
..2
..3
..4
..5
..6 ..7
nul soh stx etx eot enq ack
dle dc1 dc2 dc3 dc4 nak syn
sp !
“
# $ % &
0
1
2
3
4
5
6
@ A B C D E
F
P Q R
S T U V
‘
a
b
c
d
e
f
p
q
r
s
t
u
v
..8 ..9 ..A ..B ..C ..D ..E ..F
bel bs ht lf vt
etb can em sub esc
’
(
)
* +
7
8 9
:
;
G H I
J K
W X Y Z
[
g
h
i
j
k
w x
y
z
{
ff
fs
,
<
L
\
l
!
cr so si
gs rs us
. /
= > ?
M N O
] ˆ
m n o
} ˜ del
8
ASCII Erweiterungen, Unicode
• ASCII verwendet nur 7 Bit von einem Byte
• enthält z.B. keine Umlaute (ä, ö, ü) oder Akzente (é, ç)
9
ASCII Erweiterungen, Unicode
• ASCII verwendet nur 7 Bit von einem Byte
• enthält z.B. keine Umlaute (ä, ö, ü) oder Akzente (é, ç)
• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit
• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)
• belegt die Codes von 128-255 (bzw. 80-FF in hex)
9
ASCII Erweiterungen, Unicode
• ASCII verwendet nur 7 Bit von einem Byte
• enthält z.B. keine Umlaute (ä, ö, ü) oder Akzente (é, ç)
• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit
• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)
• belegt die Codes von 128-255 (bzw. 80-FF in hex)
• Unicode wurde als 16 Bit Codierung eingeführt
• erste 128 Zeichen stimmen mit ASCII überein
• die nächsten 128 Zeichen mit ISO Latin-1
• danach z.B. kyrillische, arabische, japanische Schriftzeichen
9
ASCII Erweiterungen, Unicode
• ASCII verwendet nur 7 Bit von einem Byte
• enthält z.B. keine Umlaute (ä, ö, ü) oder Akzente (é, ç)
• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit
• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)
• belegt die Codes von 128-255 (bzw. 80-FF in hex)
• Unicode wurde als 16 Bit Codierung eingeführt
• erste 128 Zeichen stimmen mit ASCII überein
• die nächsten 128 Zeichen mit ISO Latin-1
• danach z.B. kyrillische, arabische, japanische Schriftzeichen
• UTF-8 ist eine Mehrbyte-Codierung von Unicode (1-6 Bytes)
• Code-Länge wird durch die ersten Bits codiert
9
Zeichen und Strings
Repräsentation eines ASCII Zeichens in C, C++: char
• Zeichen-Literale in einfachen Anführungszeichen
Beispiele: ’A’, ’u’, ’D’
char zeichen = ’A ’;
• Vorsicht bei nicht-ASCII Zeichen!
10
Zeichen und Strings
Repräsentation eines ASCII Zeichens in C, C++: char
• Zeichen-Literale in einfachen Anführungszeichen
Beispiele: ’A’, ’u’, ’D’
char zeichen = ’A ’;
• Vorsicht bei nicht-ASCII Zeichen!
Repräsentation einer Zeichenfolge? (Englisch: String)
• String-Literale in doppelten Anführungszeichen
Beispiel: “AuD“
• in C gespeichert als Folge von Zeichen, terminiert durch ’\0’
'A'
'u'
'D'
'\0'
10
Strings in C
Strings in C:
• dargestellt als Array von chars fester Länge:
char test_string [8];
• C Arrays werden indiziert von 0! (hier also von 0 bis 7)
• immer genug Platz für terminierendes ’\0’ einplanen!
11
Strings in C
Strings in C:
• dargestellt als Array von chars fester Länge:
char test_string [8];
• C Arrays werden indiziert von 0! (hier also von 0 bis 7)
• immer genug Platz für terminierendes ’\0’ einplanen!
• dargestellt als Array von chars dynamischer Länge (mittels
Pointer):
char * test_string ;
• Speicher muss explizit über malloc/free
angefordert/freigegeben werden!
• Größe des Arrays komplett in eigener Verantwortung!
• sehr fehleranfällig, bitte vermeiden wenn möglich!
11
Programm: Strings in C
# include < stdio .h >
# include < string .h >
int main ()
{
char test_string [5] = " test " ; // Laenge ist 4+1
printf ( " test_string : ! % s \ n " , test_string );
char AuD_string [4];
AuD_string [0] = ’A ’;
AuD_string [1] = ’u ’;
AuD_string [2] = ’D ’;
AuD_string [3] = ’ \0 ’; // terminierende 0
printf ( " AuD_string : ! % s \ n " , AuD_string );
printf ( " Laenge : ! % lu \ n " , strlen ( AuD_string ) );
return 0;
}
12
Strings in C - Operationen
Operationen auf C Strings: definiert in string.h
• strlen(str): liefert Länge des Strings str
• strcpy(ziel, quelle): kopiert String quelle nach ziel
• ziel wird als groß genug vorausgesetzt!
• strcat(ziel, quelle): hängt String quelle an String
ziel hinten an
• ziel wird als groß genug vorausgesetzt!
• strcmp(str1, str2): vergleicht die Strings str1 und str2
• ist das Ergebnis 0, sind die Strings gleich
13
Programm: Strings in C (Fortsetzung)
# include < stdio .h >
# include < string .h >
int main ()
{
char test_string [] = " test " ;
char AuD_string [] = " AuD " ;
char resultat_string [20]; // gross genug
strcpy ( resultat_string , AuD_string );
printf ( " strcpy ! Ergebnis : ! % s \ n " , resultat_string );
int vergleich = strcmp ( resultat_string , AuD_string );
printf ( " strcmp ! Ergebnis : ! % d \ n " , vergleich );
strcat ( resultat_string , test_string );
printf ( " strcat ! Ergebnis : ! % s \ n " , resultat_string );
return 0;
}
14
Strings in C - Probleme
Probleme mit C Strings:
• terminierende ’\0’ wird vergessen
• Zuweisung nach Initialisierung schwierig
• Größenvoraussetzungen werden nicht automatisch geprüft
• Verwaltung von Strings dynamischer Länge eine Quelle der
häufigsten Programmierfehler
• aber gerade Strings dynamischer Länge werden gebraucht!
15
Strings in C++
Strings in C++:
• dargestellt als std::string
std :: string test_string ;
• Zugriff wie bei C Strings über [] Operator, indiziert von 0
std :: string test_string = " test " ;
test_string [1] = ’a ’;
• automatische Verwaltung der Größe
• nicht terminiert mit ’\0’, sondern speichert Größe direkt
• Operationen direkt in std::string eingebaut
16
Programm: Strings in C++
# include < iostream >
# include < string >
using namespace std ;
int main ()
{
string test_string = " test " ;
cout << " test_string : ! " << test_string << endl ;
string AuD_string = " BvE " ;
AuD_string [0] = ’A ’;
AuD_string [1] = ’u ’;
AuD_string [2] = ’D ’;
cout << " AuD_string : ! " << AuD_string << endl ;
cout << " Laenge : ! " << AuD_string . length () << endl ;
...
17
Programm: Strings in C++ (Fortsetzung)
...
string resultat_string ;
resultat_string = AuD_string ;
cout << " Kopieren : ! " << resultat_string << endl ;
bool vergleich = ( resultat_string == AuD_string );
cout << " Vergleich : ! " << vergleich << endl ;
resultat_string = resultat_string + test_string ;
// oder kuerzer :
// resultat_string += test_string ;
cout << " Anhaengen : ! " << resultat_string << endl ;
return 0;
}
18
Programm heute
1 Einführung
2 Mathematische Grundlagen
Mengen
Abbildungen
Zahldarstellung
Boolesche Logik
3 Elementare Datenstrukturen
Zeichenfolgen
Felder
19
Definition Feld
Definition Feld
Ein Feld A ist eine Folge von n Datenelementen (di )i=1,...,n ,
A = d1 , d2 , . . . , dn
mit n ∈ N0 .
Die Datenelemente di sind beliebige Datentypen (z.B. primitive).
Beispiele:
• A sind die natürlichen Zahlen von 1 bis 10, aufsteigend
geordnet:
A = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
• Ist n = 0, so ist das Feld leer.
20
Feld als sequentielle Liste
Repräsentation von Feld A als sequentielle Liste (oder Array)
• feste Anzahl n von Datenelementen
• zusammenhängend gespeichert
• in linearer Reihenfolge mit Index
• Zugriff auf i-tes Element über Index i: A[i]
Feld A:
A[n]
A[n-1]
...
A[2]
A[1]
A[0]
21
Beispiel sequentielle Liste
Feld A=0,8,15, Länge 3
• Beispiel in C:
int A [3];
A [0] = 0;
A [1] = 8;
A [2] = 15;
• Beispiel in C++:
std :: vector < int > A (3);
A [0] = 0; A [1] = 8; A [2] = 15;
22
Eigenschaften sequentielle Liste
Feld A mit Länge n als sequentielle Liste (Array)
• Vorteile:
• direkter Zugriff auf Elemente in konstanter Zeit mittels A[i]
• sequentielles Durchlaufen sehr einfach
• Nachteile:
• Verschwendung von Speicher falls Liste nicht voll belegt
• Verlängern der sequentiellen Liste sehr aufwendig
• Hinzufügen und Löschen von Elementen sehr aufwendig
23
C Beispiel: sequentielles Durchlaufen
Code:
int feldA [5];
int i ;
// sequentielles Durchlaufen
printf ( " feldA : ! " );
for ( i = 0; i < 5; ++ i ) {
feldA [ i ] = i * i ;
printf ( " % d ! " , feldA [ i ]);
}
printf ( " \ n " );
Ausgabe:
feldA : 0 1 4 9 16
24
Verlängern der sequentiellen Liste
Gegeben: Feld A, Länge n, als sequentielle Liste
Gewünscht: Feld A erweitert auf Länge n+1
• neuen Speicher der Größe n+1 reservieren
• alte Liste in neuen Speicher kopieren
Feld A:
neues
Feld A:
A[n+1]
A[n]
A[n-1]
...
A[2]
A[1]
A[0]
A[n]
A[n-1]
...
A[2]
A[1]
A[0]
25
C Beispiel: Verlängern der Liste
Code:
int neuesFeldA [6];
// altes Feld kopieren :
for ( i = 0; i < 5; ++ i )
neuesFeldA [ i ] = feldA [ i ];
// neues Element :
neuesFeldA [5] = 25;
// neuesFeldA ausgeben :
printf ( " neuesFeldA ! nach ! Verlaengern : ! " );
for ( i = 0; i < 6; ++ i )
printf ( " % d ! " , neuesFeldA [ i ]);
printf ( " \ n " );
Ausgabe:
neuesFeldA nach Verlaengern : 0 1 4 9 16 25
26
Löschen von Element aus Liste
Gegeben: Feld A, Länge n, als sequentielle Liste
Gewünscht: Element i aus Feld A löschen
• Element i entfernen
• Listenelemente nach i umkopieren
25
16
9
4
1
0
-
25
16
9
4
1
27
C Beispiel: Löschen von Element
Code:
// loesche erstes Element
for ( i = 1; i < 6; ++ i )
neuesFeldA [i -1] = neuesFeldA [ i ];
// setze letztes Element auf -1
neuesFeldA [5] = -1;
// neuesFeldA ausgeben :
printf ( " neuesFeldA ! nach ! Loeschen : ! " );
for ( i = 0; i < 6; ++ i )
printf ( " % d ! " , neuesFeldA [ i ]);
printf ( " \ n " );
Ausgabe:
neuesFeldA nach Loeschen : 1 4 9 16 25 -1
28
Einfügen von Element in Liste
Gegeben: Feld A, Länge n, als sequentielle Liste
Gewünscht: neues Element in Feld A an Stelle i einfügen
• Listenelemente nach i umkopieren
• Element i einfügen
-
25
16
9
4
1
25
16
9
8
4
1
29
C Beispiel: Einfügen von Element
Code:
// neues Element (8) an 3. Stelle einfuegen
for ( i = 5; i > 2; --i )
neuesFeldA [ i ] = neuesFeldA [i -1];
neuesFeldA [2] = 8;
// neuesFeldA ausgeben :
printf ( " neuesFeldA ! nach ! Einfuegen : ! " );
for ( i = 0; i < 6; ++ i )
printf ( " % d ! " , neuesFeldA [ i ]);
printf ( " \ n " );
Ausgabe:
neuesFeldA nach Einfuegen : 1 4 8 9 16 25
30
C++ Beispiel: sequentielle Listen
Code:
vector < int > feldA (5);
// sequentielles Durchlaufen
for ( int i = 0; i < 5; ++ i ) {
feldA [ i ] = i * i ;
}
// Verlaengern der Liste
feldA . resize (6);
feldA [5] = 25;
// loesche erstes Element
feldA . erase ( feldA . begin () );
feldA [5] = -1;
// neues Element (8) an 3. Stelle einfuegen
feldA . insert ( feldA . begin () + 2 , 8);
31
Ausblick: Anwendung von sequentiellen Listen
in 2D und 3D Bildern!
32
Zusammenfassung
1 Einführung
2 Mathematische Grundlagen
Mengen
Abbildungen
Zahldarstellung
Boolesche Logik
3 Elementare Datenstrukturen
Zeichenfolgen
Felder
33
Herunterladen