• Keine Ergebnisse gefunden

Übung Algorithmen und Datenstrukturen

N/A
N/A
Protected

Academic year: 2022

Aktie "Übung Algorithmen und Datenstrukturen"

Copied!
3
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Wolfgang Hönig / Andreas Ecke WS 09/10

Übung Algorithmen und Datenstrukturen

7. Übung: Zusatzaufgaben 1. Folgender Baum vom Typ nodesei gegeben (siehe AGS 3.19):

2 3 4

6

a) Schreiben Sie eine rekursive Funktionint sum(node t), welche die Summe aller Bau- melemente berechnet.

b) Stellen Sie den Aufruf der Funktion als pulsierenden Speicher dar.

Hinweis: Fassen Sie node als elementaren Datentyp auf, der z.B. mit #b<key> im pulsierenden Speicher dargestellt werden kann. Als Haltepunkt istlabel1in der ers- ten Zeile der Funktion sum zu verwenden. Der Markenkeller sei anfangs leer und der restliche Speicher des Programms soll nicht betrachtet werden.

2. In der Programmiersprache C gibt es sogenannte bitweise Operatoren wie & (AND), | (OR),^ (XOR) und~(NOT). Diese verknüpfen die beiden Operanden (bzw. bei~ nur ein Operand) Bit für Bit. Zum Beispiel gilt für das bitweise Und:

001011

& 101101

= 001001

Man sieht also, dass im Ergebnis nur an den Stellen Bits gesetzt sind, an denen sowohl Operand 1 als auch Operand 2 eine 1 hatten (daher auch der Name bitweises Und). Ent- sprechendes gilt natürlich auch für OR, welches überall dort Einsen setzt, wo in Operand 1 oder Operand 2 (oder natürlich in beiden) schon eine 1 ist, und für XOR welches entspre- chend nur 1en setzt wenn entweder in Operand 1 oder in Operand 2 (aber diesmal nicht in beiden) eine 1 steht - daher auch der Name XOR: Exklusives Oder.

Zu fast allen Operatoren gibt es auch noch Kurzformen, wenn das Ergebnis gleich in Ope- rand 1 gespeichert werden soll. Statta = a + b;kann man so schreibena += b;und statt y = y & z;einfachy &= z;

Welche Funktion erfüllt nun folgendes Programmstück?

1 void f u n c t i o n 1 (unsigned i n t ∗a , unsigned i n t ∗b ) { 2 ∗a ^= ∗b ;

3 ∗b ^= ∗a ; 4 ∗a ^= ∗b ; 5 }

3. Gegeben sei die Funktion:

1 i n t f u n c t i o n 2 (i n t a , i n t b , i n t c , i n t d ) { 2 return ( a∗b)+( c∗d ) ;

3 }

Was passiert nun, wenn man diese Funktion mit Booleschen Werten aufruft und auch den Rückgabewert als booleschen Wert interpretiert (Anmerkung: Das ist in C möglich, da es eigentlich keine booleschen Typen gibt, sondern nur Zahlen = 0 als false und Zahlen 6= 0 als true interpretiert werden)?

Wie kann man diese Funktion dann mit den regulären logischen Operatoren && und ||

schreiben? Welche Nachteile hat außerdem die Verwendung von +und *?

(2)

Lösungen 1. a) folgende Funktion summiert alle Baumelemente:

1 i n t sum ( node t ) 2 {

3 /∗l a b e l 1∗/

4 i f( t == NULL) return 0 ;

5 return t−>key+sum ( t−> l e f t )/∗$1∗/+sum ( t−>r i g h t )/∗$2∗/; 6 }

b) Haltepunkt RM Umgebung

1 2 3 4

label1 - t

#b2

label1 1 t

#b2 #b3

label1 1:1 t

#b2 #b3 #0 linker Nachfolger der 3

label1 2:1 t

#b2 #b3 #0 rechter Nachfolger der 3

label1 2 t

#b2 #b4

label1 1:2 t

#b2 #b4 #b6 linker Nachfolger der 4

label1 1:1:2 t

#b2 #b4 #b6 #0 linker Nachfolger der 6

label1 2:1:2 t

#b2 #b4 #b6 #0 rechter Nachfolger der 6

label1 2:2 t

#b2 #b4 #0 rechter Nachfolger der 4 Der Markenkeller wird natürlich noch abgebaut, allerdings ist dies bei uns nicht sicht- bar, da nur beim Funktionsaufruf protokolliert wird.

2. Die Funktion betrachtet man am besten erst einmal für ein einzelnes Bit und überträgt das Verhalten dann auf die gesamte Zahl.

Nach der ersten Anweisung gilt nun a := a^b. Die zweite Anweisung berechnet nun - da a ja bereits verändert wurde -b := b ^ (a^b) = a ^ (b^b) = a ^ 0 = a.

Die dritte Anweisung berechnet nun a := (a^b) ^ a = b ^ (a^a) = b. Somit enthält nun a das Bit, welches am Anfang in b stand und umgekehrt. Überträgt man dieses Verhal- ten auf die gesamte Funktion, vertauscht alsofunction1die Werte in den Speicherplätzen, auf die a und b zeigen, und das ganz ohne Hilfsvariable!

3. Der Ansatz lautet hier natürlich, das man prüfen muss, was bei den Operationen + und* passiert, wenn man sie auf 2 Zahlen die jeweils 0 oder ungleich 0 sind, anwendet. Dabei erkennt man recht schnell, dass die Multiplikation genau dann eine 0 ergibt, wenn einer der Faktoren 0 ist, oder anders gesagt: a*b ist genau dann ungleich 0, wenn sowohl a als auch b ungleich 0 sind. Dies entspricht ziemlich genau der logischen Und-Funktion&&.

Entsprechend gilt für die Addition, dass die Summe genau dann ungleich 0 ist, wenn min- destens einer der Summanden ungleich 0 ist. Damit entspricht + dem logischen Oder||.

Somit könnte man in der Funktion statt return(a∗b)+(c∗d); auch return (a && b) || (c && d); schreiben.

Einen Nachteil hat jedoch die Verwendung von + und *: Sie stimmt nicht immer. Zum Beispiel, wenn man die beiden Werte −4 und +4, welche ja beide ungleich 0 und damit true sind, mit der Addition (als Oder-Ersatz) verknüpft, so kommt trotzdem 0 - false -

(3)

raus, was natürlich nicht erwünscht ist. Dies kann man verhindern, indem man nur noch vorzeichenlose Zahlen benutzt.

Doch dann gibt es immer noch ein zweites Problem: Es kann bei Addition oder Multi- plikation zweier großer Zahlen zum Überlauf kommen, durch welche sich dann doch wie- der 0 ergibt. Seien zum Beispiel a und b ganze Zahlen mit je 8 Bit (unsigned char) mit a = 0110 11012 und b = 1001 00112. Dann ist a+b = (1) 0000 00002, wobei die erste 1 jedoch wegen der 8Bit Darstellungsbreite wegfällt. Damit ist die Summe zweier Zahlen ungleich 0 wieder eine 0 und die Funktion entspricht nicht mehr dem||. Deswegen ist die Verwendung von &&und|| statt* und+ doch vorzuziehen.

Der letzte Nachteil der Verwendung von *und +statt&&und||betrifft die Geschwindig- keit. Logische Befehle sind im Allgemeinen natürlich bedeutend schneller auszuführen als arithmetische, was vor allem für zeitkritische Programme eine Rolle spielt.

Referenzen

ÄHNLICHE DOKUMENTE

Wolfgang Hönig WS 09/101. Übung Algorithmen

• Suchbaum: Für jeden Knoten gilt: alle Schlüssel im linken Teilbaum sind kleiner und alle Schlüssel im rechten Teil- baum sind größer als der Schlüssel des Knotens. •

Herstellen heap-Eigenschaft (jeder Wurzelknoten muss grö- ßeren Wert haben als seine Nachfolger) (Phase 1). a) sinkenlassen für jeden Knoten in einer Ebene / Schritt (von unten

Geben Sie eine BNF-Definition B an, die folgende Sprache beschreibt (siehe auch Zusatzaufgaben der 33. Ist die Grammatik (bzw. BNF-Definition)

minimale Beispiele der Wörter aufschreiben2. aktuelles Wort und

Hinweis: Wenn die Übung immer noch zu langweilig ist, lohnt es sich alle Syntaxdia- grammsysteme der obigen Aufgaben in die entsprechende EBNF

Alphabet (Σ) nichtleere, endliche Menge zulässiger Symbole für die Wortbildung („Zeichenvorrat“). Wort endliche Folge

Diese Sprachen sollen nun miteinander verket- tet werden, wobei jede Sprache genau einmal in der Verkettung enthalten ist, jedoch die Reihenfolge der Verkettungen unterschiedlich