Ein Doppel-Axel in C (2) lsearch, tsearch, hsearch

Größe: px
Ab Seite anzeigen:

Download "Ein Doppel-Axel in C (2) lsearch, tsearch, hsearch"

Transkript

1 Ein Doppel-Axel in C (2) lsearch, tsearch, hsearch Axel-Tobias Schreiner, Universität Ulm Kernighan und Ritchie s fünftes Kapitel 1 ist für jeden C Programmierer natürlich Pflicht. Die Kür besteht bei System V offensichtlich darin, Suchfunktionen nicht mehr selbst zu programmieren, sondern die verschiedenen Lösungen zu diesem Thema aus der Standard-Bücherei korrekt einsetzen zu können. In der letzten Ausgabe der Sprechstunde wurden Beispiele für die Verwendung der Funktionen qsor t() und bsearch() gezeigt; außerdem wurde die lsearch()-familie vorgestellt. Jetzt geht es mit dem üblichen Test weiter einem Programm zur Zählung der Häufigkeit von Worten in einem Text und wir betrachten auch noch die Funktionsfamilien hsearch() und tsearch(). Langsam zählen lsearch() und binary() lsearch() kann man zur Lösung des Häufigkeitsproblems höchstens als abschreckendes Beispiel verwenden. Als Kür für Zeiger eignet es sich aber ganz gut: typedef struct { char * word; int freq; Object; /* ein Wort */ 1...über Zeiger und Vektoren.

2 static Object * table; /* Vektor aller Worte */ static int t, mt; /* aktuelle und maximale Anzahl */ static int cmpw(a, b) register Object * a, * b; /* Worte vergleichen */ { return strcmp(a >word, b >word); static int cmpf(a, b) register Object * a, * b; /* Haeufigkeit vergleichen */ { register int c; return (c = a >freq b >freq)? c : strcmp(a >word, b >word); alpha() { register int i; Qsort(table, t, cmpw); for (i = 0; i < t; ++ i) puts(table[i].word); frequency() { register int i; Qsort(table, t, cmpf); for (i = 0; i < t; ++ i) puts(table[i].word); Da die Worte sicher verschieden lang sind, und da es wahrscheinlich ein paar sehr lange Worte gibt, speichern wir auch die Texte der Worte dynamisch. Die Tabelle mit den Zeigern auf die Worte und den Häufigkeitszählern wird selbstverständlich dynamisch unterhalten. lsearch() sortiert die Tabelle nicht; für die Ausgabe muß 2 deshalb die Tabelle jeweils nach dem richtigen Kriterium sortiert werden. Die 2 Qsor t() ist ein Makro aus der vorigen Ausgabe, der für die richtigen Umwandlungen bei qsor t() sorgt und die Elementgröße selbst berechnet.

3 ernsthafte Arbeit leistet count(), denn hier muß vor allem der Vektor table[] dynamisch verwaltet werden: count(word) register char * word; { char * malloc(), * realloc(); Object key, * kp; extern int inc; if (t == mt) if (! table) if (table = (Object *) malloc(inc * sizeof(object))) mt = inc; else fputs("no room\n", stderr), exit(1); else if (! (table = (Object *) realloc(table, (mt += inc) * sizeof(object)))) fputs("no more room\n", stderr), exit(1); t ist die aktuelle Länge der Tabelle, mt die verfügbare Länge. Sind t und mt gleich, ist in der Tabelle kein Platz (mehr) vorhanden. Gibt s dann noch keine Tabelle, wird sie mit malloc() angelegt, sonst wird sie mit realloc() verlängert und dabei unter Umständen intern umkopiert. inc können wir global beeinflussen es ist selbstverständlich, daß man den Tabellenplatz nicht nur um einzelne Elemente vergrößert. key.word = word; kp = lsearch(& key, table, & t, sizeof key, cmpw); if (kp >word == word) kp >word = strsave(word), kp >freq = 1; else ++ kp >freq;

4 Anschließend wird ein Tabellenelement key als Suchobjekt initialisiert und damit lsearch() bemüht. Der Trick besteht darin, das Wort selbst erst dann dynamisch zu speichern, wenn es wirklich neu ist, wenn also lsearch() wirklich key in die Tabelle kopiert hat und das Tabellenelement auf den Puffer zeigt, der an count() selbst übergeben wurde. strsave() findet man zum Beispiel im Abschnitt 5.6 bei Kernighan und Ritchie oder als strdup() bei XENIX. An Stelle von lsearch() kann man auch unsere Funktion binary() 3 aufrufen. In diesem Fall ist natürlich der Aufruf von qsor t() in alpha() unnötig. Hier sind ein paar Meßergebnisse: 3 Diese Funktion aus dem ersten Teil des Artikels sucht binär und fügt bei Bedarf ein Element so ein, daß die Tabelle sortiert bleibt.

5 count() user system Aktivität inc alpha() freqency() Summe heap Leerlauf lsearch() binary() Leerlauf lsearch() binary() lsearch() binary() Im ersten Teil der Tabelle wurde der SpreadSheet-Artikel aus der vorigen Ausgabe der unix/mail bearbeitet, im zweiten Teil nur die sortierte Liste der Worte, im dritten Teil die gleiche Liste, aber mit sor t -rin umgekehrter Reihenfolge. Man beobachtet natürlich, daß binary() wesentlich effizienter ist als lsearch(). Man sieht aber auch, daß 50 eine schlechte Wahl für inc war: malloc() fordert von sbrk() Speicher in größeren Stücken an; kleinere Schritte in der Tabellenvergrößerung wirken sich folglich ungünstig aus. Eine umgekehrt sortierte Liste von Worten ist der ungünstigste Fall für binary() trotzdem funktioniert die Funktion hier immer noch so gut wie lsearch()! Daß bei gleicher Eingabe im dritten Teil mehr dynamischer Speicherplatz als im zweiten Teil verbraucht wird, liegt an der Verteilung der Wortlängen; vergrößert man inc wieder auf 100, geht der Speicherplatzverbrauch

6 auch wieder zurück. Suchbäume tsearch() und twalk() In Programmiervorlesungen stellt man das Häufigkeitsproblem normalerweise als Aufgabe zu struct und dynamisch aufgebauten Datenstrukturen, nämlich zu binären Bäumen: typedef struct node Node; /* Knoten im Baum */ struct node { char * word; int freq; /* die Information */ Node * left, * right; /* die Unterbaeume */ ; In einer früheren Sprechstunde habe ich den üblichen iterativen Algorithmus gezeigt, mit dem man Worte so in einen binären Baum einträgt, daß er bei einer postorder- Traverse 4 sortiert erscheint. Inzwischen gibt es diesen Algorithmus als Büchereifunktion: #include <search.h> /* definiert VISIT */ char * tsearch(), * tfind(), * tdelete(); void twalk(); #define Tsearch(key, rootp, compar) \ 4 Nach Don Knuth s The Art of Computer Programming (Addison-Wesley 1968) unterscheidet man preorder (Wurzel vor Unterbäumen bearbeiten), postorder (Wurzel zwischen linkem und rechtem Unterbaum) und endorder (Wurzel nach Unterbäumen). In der zweiten Auflage wurde postorder zur sinnvolleren inorder, und endorder dann zu postorder. Bei System V glaubt man noch an die erste Auflage.

7 ((Object **) tsearch((char *) (key), /* gesuchtes Object */ \ (char **) (rootp), /* > > Wurzel */ \ (int (*)()) (compar))) /* Vergleichsfunktion */ #define Tfind(key, rootp, compar) \ ((Object **) tfind((char *) (key), /* gesuchtes Object */ \ (char **) (rootp), /* > > Wurzel */ \ (int (*)()) (compar))) /* Vergleichsfunktion */ #define Tdelete(key, rootp, compar) \ ((Object **) tdelete((char *) (key), /* gesuchtes Object */ \ (char **) (rootp), /* > > Wurzel */ \ (int (*)()) (compar))) /* Vergleichsfunktion */ #define Twalk(root, action) \ (twalk((char *) (root), /* > Wurzel */ \ (void (*)()) (action))) /* Aktion */ tfind() sucht Information in Form eines Zeigers(!) key in einem Suchbaum, auf dessen Wurzel ein Zeiger zeigen muß, dessen Adresse (Zeiger auf Zeiger!) als rootp übergeben wird. Der Suchbaum ist postorder-sortiert im Sinne der Vergleichsfunktion compar. Die Vergleichsfunktion erhält, wie bei den bisher betrachteten Suchoperationen, wieder zwei Zeiger des Typs, der als erstes Argument an tfind() geliefert wird. Als Resultat liefert tfind() bei Mißerfolg natürlich einen Nullzeiger, bei Erfolg aber einen Zeiger auf den Punkt im Suchbaum, bei dem die Information als Zeiger gespeichert ist, die compar als gleich zur Argument- Information betrachtet. Ein Unterschied zwischen lfind() und tfind() ist also, daß lfind() ein Resultat vom Typ des ersten Arguments liefert, tfind() aber einen Zeiger auf ein Datum mit dem Typ des ersten Arguments. tsearch() funktioniert wie tfind(), trägt aber bei Bedarf den als erstes Argument übergebenen Informationszeiger in den Suchbaum ein. tsearch() liefert einen Nullzeiger entweder, wenn als rootp ein Nullzeiger übergeben wird (das ist ein

8 Fehler), oder wenn kein dynamischer Speicherplatz zum Ausbau des Baums mehr vorhanden ist. tsearch() liefert einen Zeiger auf seinen ersten Argumentwert, wenn genau der Argumentwert im Baum gefunden oder gerade eingetragen wurde. Wir können also count() wieder implementieren: static int nel; /* Anzahl verschiedener Worte */ static char * root; /* Zeiger auf den Baum; NULL, also leer */ count(word) register char * word; { char * malloc(); register Object ** opp; Object key; key.word = word; if (! (opp = Tsearch(& key, & root, cmpw))) fputs("no tree room\n", stderr), exit(1); if (*opp == & key) { if (! (*opp = (Object *) malloc(sizeof(object)))) fputs("no node room\n", stderr), exit(1); (*opp) >word = strsave(word); (*opp) >freq = 1; ++ nel; else ++ (*opp) >freq; Object, strsave() und die Vergleichsfunktion cmpw() werden vom lsearch()-beispiel aus dem ersten Teil des Artikels übernommen. Wieder wird das Suchobjekt key initialisiert und damit tsearch() aufgerufen. Beim ersten Mal sollte ein leerer Baum als zweites Argument übergeben werden: root hat, als globale Variable, einen Nullzeiger als Anfangswert, und dessen Adresse repräsentiert dann einen leeren Baum.

9 tdelete() funktioniert ähnlich wie tfind(), das heißt, Information wird im Suchbaum lokalisiert. Anschließend verändert tdelete() den Suchbaum allerdings so, daß diese Information nicht mehr im Suchbaum steht: tdelete() löscht ein Element aus dem Suchbaum. Eine äquivalente Funktion gibt es bei den anderen Funktionsfamilien nicht. tdelete() ist jedoch keine glückliche Lösung um effizient einen ganzen Suchbaum zu löschen. Als Resultat liefert tdelete() bei Erfolg entweder einen Zeiger auf die Information im Vorgänger des gelöschten Elements im Suchbaum, einen Zeiger auf die Information im gerade gelöschten(!) Element, wenn es die Wurzel des Suchbaums war, oder einen Nullzeiger, wenn nichts gelöscht werden konnte. Dieser Aspekt von tdelete() ist nicht optimal überlegt. Gegenüber einer von lsearch() unterhaltenen Liste hat ein von tsearch() konstruierter Baum den Vorteil, daß er meistens effizienter durchsucht werden kann, und daß die Information im Baum auch in sortierter Reihenfolge erreichbar ist. Gegenüber unserer Funktion binary() sucht tsearch() meistens weniger effizient, muß aber dafür bei neuen Einträgen nichts verschieben. Baumtraversen realisiert die Funktion twalk(): für jedes Blatt im Suchbaum ruft sie eine vom Benutzer zu programmierende Funktion einmal auf, für jeden anderen Knoten dreimal. Die verschiedenen Argumente sind ein bißchen kompliziert: twalk() erhält direkt den Zeiger auf die Wurzel des Suchbaums ( ein Sternchen weniger als tsearch() ) und dazu die Benutzerfunktion. Die Benutzerfunktion erhält als erstes Argument einen Zeiger auf den Zeigerwert, der im Suchbaum eingetragen ist ( ein Sternchen mehr als die Vergleichsfunktion ) und der gerade besucht wird, als zweites Argument (C-Kür, Sie erinnern sich?) einen enum-wert, nämlich leaf, preorder, postorder oder endorder, und als drittes Argument das aktuelle Baumniveau. alpha() ist eine typische Anwendung von twalk(): static void visit(opp, order) register Object ** opp; VISIT order;

10 { switch (order) case leaf: case postorder: puts((*opp) >word); alpha() { twalk(root, visit); VISIT ist der enum-typ und stammt aus der öffentlichen Definitionsdatei search.h. visit() ist unsere Benutzerfunktion wir geben Worte alphabetisch aus, wenn wir Blätter oder Knoten in postorder erreichen. Hängt von switch() nur eine Anweisung ab, kann man ihr die case-marken voranstellen und auf die geschweiften Klammern verzichten. Für frequency(), die Ausgabe nach Häufigkeit, muß man umsortieren. Wir verwenden twalk() dazu, dynamisch einen Vektor von Zeigern auf unsere Object- Strukturen zu konstruieren. Den Vektor können wir dann mit qsor t() nach Häufigkeit sortieren und ausgeben: static int cmpf(a, b) register Object ** a, ** b; /* Vergleich */ { register int c; return (c = (*a) >freq (*b) >freq)? c : cmpw(*a, *b); static Object ** ptr; /* naechstes Vektorelement */ static void enter(opp, order) Object ** opp; VISIT order; /* baut Vektor */ { switch (order) case leaf: case endorder: *ptr++ = *opp;

11 frequency() { register Object ** table; register int i; char * malloc(); if (nel) { if (! (table = (Object **) malloc(nel * sizeof(object *)))) fputs("no room for index\n", stderr), exit(1); ptr = table; twalk(root, enter); Qsort(table, nel, cmpf); for (i = 0; i < nel; ++ i) puts(table[i] >word); free(table); Bei der Vergleichsfunktion cmpf() ist Vorsicht geboten: wir sortieren nicht mehr einen Vektor von Object-Strukturen sondern einen Vektor von Zeigern darauf. Da der Komponentenverweis -> Vorrang vor der Verweisoperation * hat, muß man wie oben klammern. Da die Werte der.freq-komponenten positiv sind, kann man die Differenz als Resultat des Vergleichs heranziehen. Es lohnt sich leider, dieses Beispiel auch noch auszuprobieren:

12 count() user system Eingabe alpha() freqency() Summe heap Artikel sortiert core dump sortiert* Artikel sortiert sort -r Vergleicht man mit der Tabelle zu lsearch() und binary() stellt man fest, daß tsearch() im Normalfall erheblich weniger Rechenzeit verbraucht dafür ist der Speicherverbrauch höher, denn irgendwo muß der Suchbaum schließlich stehen. Weniger schön ist die Reaktion, wenn die Worte sortiert eintreffen: der binäre Baum artet in eine lineare Liste aus und die Verfolgung von Zeigern ist dann noch geringfügig langsamer als das Absuchen eines Vektors. Der Zeitverlust ist nicht das einzige Problem. Bei einem normalen binären Baum muß twalk() rekursiv traversieren ein entarteter Baum verursacht dann entweder einen hohen Platzverbrauch auf dem Stack oder, wie hier bei XENIX den Prozeßabbruch. Mit einem bösartigen Trick kann man das Problem teilweise vermeiden: sortiert* bezieht sich auf einen Versuch, bei dem zuerst durch Eingabe von 52 Worten ein möglichst balancierter Baum gebildet wurde, zu dem dann erst die sortierte Liste der Worte aus dem Artikel hinzugefügt wurde. Die 52 Worte waren die Klein- und Großbuchstaben des Alphabets; die Balance des Baums wurde durch Verwendung des in einer früheren Spalte beschriebenen unsort-filters approximiert, der aus einer sortierten Eingabe einen Suchbaum minimaler Höhe bildet und ihn dann in preorder ausgibt, wodurch er bei der Eingabe zu tsearch() wieder mit minimaler Höhe

13 aufgebaut wird. Daß es auch anders geht, demonstriert der zweite Teil der Tabelle. Er beruht auf meiner Implementierung der tsearch()-funktionen mit Hilfe von binary threaded trees, 5 bei denen die Nullzeiger in den Blättern des Suchbaums so umfunktioniert werden, daß man preorder- und postorder-traverse iterativ ablaufen lassen kann. Für entartete Bäume funktionieren diese Funktionen etwas schlechter als binary(), aber als iterative Algorithmen vermeiden sie den hohen Platzverbrauch auf dem Stack mit seinen unangenehmen Konsequenzen. Klotzen malloc() Warum benötigt die Lösung mit binary threaded trees weniger dynamischen Speicherplatz? Wie im Kapitel 8 bei Kernighan und Ritchie nachzulesen ist, muß malloc() extern zu jeder vergebenen Speicherfläche Information aufbewahren, mit deren Hilfe free() später noch die Größe der Speicherfläche feststellen kann. Unsere Object-Struktur ist nicht sehr groß. Fordert man viele derart kleine Flächen an, die man ja in unserem Beispiel ohnehin nicht wieder freigibt, fällt die unsichtbare Information für free() stark gegenüber der nutzbaren Information in jedem Object ins Gewicht. Es ist also besser, wenn man bei count() nicht so sehr kleckert: count(word) register char * word; { char * malloc(); extern int inc; register Object ** opp; 5 Die Quellen sind zu lang für diese Spalte. Sie stehen im Kapitel 18 der Buchausgabe der UNIX Sprechstunde Hanser 1987 und auf der Diskette zu diesem Buch.

14 static Object * table; static int t; /* Speicherstueck */ if (! t &&! (table = (Object *) malloc((t = inc) * sizeof(object)))) fputs("no room\n", stderr), exit(1); table[ t].word = word; if (! (opp = Tsearch(& table[t], & root, cmpw))) fputs("no tree room\n", stderr), exit(1); if (*opp == & table[t]) ++ nel, (*opp) >word = strsave((*opp) >word), (*opp) >freq = 1; else ++ t; ++ (*opp) >freq; So holt man sich von malloc() Platz für inc Worte und gibt ihn dann mit absteigenden Indizes an den Suchbaum ab. Gibt man den Speicherplatz nicht mehr frei, kann man ihn auch direkt mit dem Systemaufruf sbrk() beim Systemkern 6 anfordern. Der Aufruf ist identisch zu malloc(). Es liegt zwar nahe, diese Funktion im Stil des lsearch()-beispiels so auszubauen, daß der Vektor table[] bei Bedarf mit realloc() verlängert wird, denn dann kann man sich den zusätzlich dynamisch angelegten Vektor für frequency() sparen, aber diese Lösung geht schief: Ist hinter der an realloc() übergebenen Fläche kein Platz mehr vorhanden, kopiert realloc() stillschweigend in eine neue, größere Fläche um. Die Zeiger auf die alte Fläche, die dann per tsearch() in unserem Suchbaum gespeichert sind, zeigen anschließend ins Leere und später in eine Gegend, die malloc() vermutlich neu vergeben hat! Man kann sich dadurch behelfen, daß man an Stelle 6 sbrk() wird in der System V Interface Definition nicht mehr erwähnt. Für malloc() gibt es eine neue Implementierung, bei der man kleine Blöcke bevorzugt behandeln lassen kann. Meine Versuche bei XENIX endeten allerdings mit einer Endlosschleife.

15 von Zeigern im Suchbaum Indexwerte in den Vektor table[] speichern läßt, denn diese Indexwerte ändern sich natürlich nicht, wenn realloc() den Vektor umkopiert: static Object * table; static int t, mt; static char * root; count(word) register char * word; { char * malloc(), * realloc(); extern int inc; register int * ip; if (t == mt) if (! table) if (table = (Object *) malloc(inc * sizeof(object))) mt = inc; else fputs("no room\n", stderr), exit(1); else if (! (table = (Object *) realloc(table, (mt += inc) * sizeof(object)))) fputs("no more room\n", stderr), exit(1); table[t].word = word, table[t].freq = 0; if (! (ip = (int *) Tsearch(t, & root, cmpw))) fputs("no tree room\n", stderr), exit(1); if (*ip == t) table[t].word = strsave(table[t].word), ++ t; ++ table[*ip].freq; static visit(ip, order) register int * ip; register VISIT order; { switch (order) case leaf: case postorder: puts(table[*ip].word);

16 int-werte kann man an Stelle von Zeigern übergeben, aber dadurch ändert sich natürlich die Interpretation des Resultattyps von tsearch(). Nach wie läßt alpha() durch twalk() den Baum traversieren, aber auch bei visit() taucht jetzt ein anderer Typ aus dem Suchbaum auf wie immer der gleiche, den tsearch() als Resultat liefert, und damit ein Sternchen mehr als das erste Argument von tsearch(). Die Funktion frequency() befaßt sich mit dem Vektor table[] und wurde deshalb schon im lsearch()-beispiel gezeigt. Raten hsearch() Wenn man zum Beispiel nur die 26 Buchstaben des Alphabets unterscheiden muß, wird man kaum einen Suchbaum bemühen. Für kleine Wertemengen stellt man einen Vektor zur Verfügung und berechnet die Indexwerte mit einer Funktion, die einen Wert einem Vektorelement zuordnet. Auf dieser Idee beruhen die sogenannten Hash-Verfahren, bei denen ein Vektor fixer Länge als Tabelle verwendet wird. Eine Hash-Funktion berechnet aus dem Suchschlüssel einen Index in die Tabelle, und so wird zunächst überhaupt keine Vergleichsoperation benötigt. Da jedoch viele mögliche Suchschlüssel (bei uns alle vorstellbaren Worte) wenigen Tabellenplätzen gegenüberstehen, kann die Hash- Funktion nicht eindeutig sein, und man muß den Suchschlüssel wenigstens mit einem Tabelleneintrag vergleichen. Streut die Hash-Funktion sehr gut, bleibt s bei dem einen Vergleich und das Verfahren ist jeder anderen Methode überlegen. Bildet die Hash-Funktion mehrere tatsächlich verwendete Suchschlüssel auf den gleichen Tabelleneintrag ab, muß man einen Algorithmus zur Auflösung der Kollisionen verwenden. Dieser Algorithmus hat oft zur Folge, daß aus einer Hash-Tabelle keine Einträge gelöscht werden können die Tabelle muß also größer angelegt werden,

17 als die maximal erwartete Anzahl von Einträgen, denn die Auflösung von Kollisionen wird natürlich schwieriger, wenn die Tabelle fast voll ist. hsearch() implementiert ein Hash-Verfahren. Im Gegensatz zu allen anderen Suchfunktionen kann hsearch() jedoch nur eine einzige, unsichtbare Tabelle manipulieren. Sie wird mit hcreate() erzeugt dabei legt man ihre Größe fest und sie kann mit hdestroy() insgesamt zerstört werden. hsearch() folgt völlig anderen Konventionen als die anderen Suchfunktionen: das erste Argument ist eine Struktur(!) vom Typ ENTRY, der in der öffentlichen Definitionsdatei search.h vereinbart wird; das zweite Argument ist der enum-wert FIND, wenn nur gesucht werden soll, oder ENTER, wenn bei Bedarf auch eingetragen werden soll. Auch diese Werte sind in search.h definiert. ENTRY hat eine erste Komponente.key, die auf den String zeigt, der als Suchschlüssel verwendet werden soll. Die zweite Komponente.data ist ein (beliebiger) Zeiger. hsearch() liefert als Resultat einen Zeiger auf einen ENTRY in der Hash-Tabelle (also auf eine Kopie des ersten Arguments) und im Fehlerfall einen Nullzeiger, wenn es bei FIND keinen entsprechenden Eintrag gibt, oder wenn bei ENTER die Tabelle voll ist. Da die Hash-Tabelle von hsearch() verborgen wird und ohnehin nicht sortiert ist, müssen wir diesmal alle Worte selbst noch auffädeln: #include <search.h> typedef struct { /* unsere Information fuer.data */ ENTRY * next; /* lineare Liste der Worte */ int freq; /* Haeufigkeit */ Data; /* Zugriffsmakros */ #define Ekey(ep) ((ep) > key) /* Wort */ #define Edata(ep) ((Data *) (ep) > data) /* Information */ #define Efreq(ep) (Edata(ep) > freq) /* Haeufigkeit */

18 #define Enext(ep) (Edata(ep) > next) /* lineare Liste */ static int nel; /* Anzahl Worte */ static ENTRY * list; /* lineare Liste */ Mit Zugriffsmakros kann man allzu schlimme Zeigerausdrücke vermeiden. Sie werden für jede interessante Komponente einmal formuliert, hängen zweckmäßigerweise von einem Zeiger auf ein Element der Hash-Tabelle ab, und sind nebeneffektfrei und als L-Werte formuliert, damit man sie in jedem Kontext verwenden kann. count() legt beim ersten Aufruf eine Hash-Tabelle mit inc Einträgen an: count(word) register char * word; { char * malloc(); ENTRY item, * ep, * hsearch(); static Data data; extern int inc; if (! list &&! hcreate(inc)) fputs("no hash room\n", stderr), exit(1); Ekey(& item) = word, Edata(& item) = & data; Anschließend wird das Suchobjekt gebildet. data ist static definiert und hat damit eine.freq-komponente mit Wert 0. Jetzt können wir hsearch() bemühen: if (! (ep = hsearch(item, ENTER))) fputs("no more hash room\n", stderr), exit(1); if (! Efreq(ep)) { if (! (Edata(ep) = (Data *) malloc(sizeof(data)))) fputs("no data room\n", stderr), exit(1); Ekey(ep) = strsave(word), Efreq(ep) = 1; Enext(ep) = list, list = ep; ++ nel;

19 else ++ Efreq(ep); Ist dann die.freq-komponente immer noch 0, wurde unser Suchobjekt gerade kopiert, das heißt, in der Hash-Tabelle stehen jetzt Zeiger auf unser word (auf unserem Stack!) und auf unsere Struktur data. Wir speichern deshalb das Wort dynamisch, legen die Information data dynamisch an, verketten mit unserer Liste und initialisieren den Häufigkeitszähler. Auch hier sollte man malloc() entlasten und größere Blöcke auf einmal anfordern. alpha(), frequency() und die zum Sortieren nötigen Vergleichsfunktionen sind Variationen zu einem bekannten Thema wenn man unsere Zugriffsmakros verwendet: static int cmpw(a, b) register ENTRY ** a, ** b; { return strcmp(ekey(*a), Ekey(*b)); alpha() { visit(cmpw); static int cmpf(a, b) register ENTRY ** a, ** b; { register int c; return (c = Efreq(*a) Efreq(*b))? c : cmpw(a, b); frequency() { visit(cmpf);

20 visit() leistet in beiden Fällen die gleiche Arbeit: für die lineare Liste muß ein Vektor mit Zeigern angelegt werden, der dann per qsor t() sortiert und ausgegeben werden kann. Man könnte auch wieder in count() mit realloc() einen Vektor dynamisch vergrößern und in der Hash-Tabelle als.data nur Indexwerte speichern, aber die vorliegende Lösung ist vermutlich klarer: static visit(cmp) int (* cmp)(); { register ENTRY ** table, ** tp, * ep; register int i; char * malloc(); if (nel) { if (! (table = (ENTRY **) malloc(nel * sizeof(entry *)))) fputs("no room for index\n", stderr), exit(1); for (ep = list, tp = table; ep; ep = Enext(ep)) *tp++ = ep; Qsort(table, nel, cmp); for (i = 0; i < nel; ++ i) puts(ekey(table[i])); free(table); Wie gut das Hash-Verfahren funktioniert, zeigt folgende Tabelle:

21 count() user system inc Eingabe alpha() freqency() Summe heap 966 Artikel sortiert Artikel sortiert Artikel sortiert Man sieht, daß das Hash-Verfahren selbst besser funktioniert als der Einsatz von Suchbäumen. Muß man sortiert ausgeben, benötigen bei unserem Beispiel beide Methoden insgesamt gleich viel Zeit und Speicherplatz. Das Hash-Verfahren ist vielleicht etwas komplizierter zu codieren, hat dafür aber den Vorteil, daß es auch bei sortierter Eingabe nicht zusammenbricht. Sehr wesentlich ist, daß das Verfahren auch dann nahezu gleich schnell abläuft, wenn die Tabelle mit 966 Worten 7 vollständig gefüllt wird. 7 Fordert man mit hcreate() genau 966 Tabelleneinträge an, kann man 1023 Worte speichern hcreate() macht die Tabelle möglicherweise etwas größer, damit die Hash-Methode korrekt funktioniert. Füllt man die Tabelle wirklich ganz, ändert sich das Zeitverhalten kaum.

22 Zusammenfassung Ist jetzt die richtige Wahl so schwer, daß man die nächste Suchoperation doch wieder selber programmiert? Ich glaube nicht. Beim Schreiben dieses Artikels habe ich mir vor allem die Aufrufkonventionen aller Funktionen klar gemacht, und in Zukunft würde ich folgendermaßen vorgehen: hsearch() ist allen anderen Methoden überlegen, falls man nicht (viele) Elemente wieder löschen muß, oder den Platzbedarf überhaupt nicht voraussehen kann, oder falls man nicht (oft) im Währenden sortiert ausgeben muß. lsearch() hat meines Erachtens keine mildernden Umstände. Für binary() spricht dagegen eine wesentlich verbesserte Effizienz sowie die Möglichkeit, daß man jederzeit garantiert neue und/oder sortierte Information zur Tabelle insgesamt hinzufügen und die Tabelle dann mit qsor t() für binary() wieder verwendbar machen kann. binary() würde ich verwenden, wenn ich den Platzbedarf nicht kenne, viel suchen und wenig neu eintragen muß, und vor allem, wenn häufig aber nicht vorhersehbar mit sortierter Information zu rechnen ist. tsearch() funktioniert so gut wie hsearch(), wenn sortiert ausgegeben werden muß, und wenn die angebotene Information nicht entartet. Bei hsearch() muß ein String als Suchschlüssel verwendet werden, bei tsearch() liefert man die Vergleichsfunktion selbst. Bäume können beliebig wachsen, Hash-Tabellen nicht, und die Probleme bei sortierter Information habe ich in meiner Implementierung entschärft.

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen Binäre Bäume 1. Allgemeines Binäre Bäume werden grundsätzlich verwendet, um Zahlen der Größe nach, oder Wörter dem Alphabet nach zu sortieren. Dem einfacheren Verständnis zu Liebe werde ich mich hier besonders

Mehr

Kapiteltests zum Leitprogramm Binäre Suchbäume

Kapiteltests zum Leitprogramm Binäre Suchbäume Kapiteltests zum Leitprogramm Binäre Suchbäume Björn Steffen Timur Erdag überarbeitet von Christina Class Binäre Suchbäume Kapiteltests für das ETH-Leitprogramm Adressaten und Institutionen Das Leitprogramm

Mehr

4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes.

4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes. Binäre Bäume Definition: Ein binärer Baum T besteht aus einer Menge von Knoten, die durch eine Vater-Kind-Beziehung wie folgt strukturiert ist: 1. Es gibt genau einen hervorgehobenen Knoten r T, die Wurzel

Mehr

Folge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Folge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12 Grundlagen: Folge 19 - Bäume 19.1 Binärbäume - Allgemeines Unter Bäumen versteht man in der Informatik Datenstrukturen, bei denen jedes Element mindestens zwei Nachfolger hat. Bereits in der Folge 17 haben

Mehr

Lernziele: Ausgleichstechniken für binäre Bäume verstehen und einsetzen können.

Lernziele: Ausgleichstechniken für binäre Bäume verstehen und einsetzen können. 6. Bäume Lernziele 6. Bäume Lernziele: Definition und Eigenschaften binärer Bäume kennen, Traversierungsalgorithmen für binäre Bäume implementieren können, die Bedeutung von Suchbäumen für die effiziente

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Der Name BEREICH.VERSCHIEBEN() ist etwas unglücklich gewählt. Man kann mit der Funktion Bereiche zwar verschieben, man kann Bereiche aber auch verkleinern oder vergrößern. Besser wäre es, die Funktion

Mehr

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.

Mehr

1 topologisches Sortieren

1 topologisches Sortieren Wolfgang Hönig / Andreas Ecke WS 09/0 topologisches Sortieren. Überblick. Solange noch Knoten vorhanden: a) Suche Knoten v, zu dem keine Kante führt (Falls nicht vorhanden keine topologische Sortierung

Mehr

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung

M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung M. Graefenhan 2000-12-07 Aufgabe Lösungsweg Übungen zu C Blatt 3 Musterlösung Schreiben Sie ein Programm, das die Häufigkeit von Zeichen in einem eingelesenen String feststellt. Benutzen Sie dazu ein zweidimensionales

Mehr

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als

Mehr

Idee: Wenn wir beim Kopfknoten zwei Referenzen verfolgen können, sind die Teillisten kürzer. kopf Eine Datenstruktur mit Schlüsselwerten 1 bis 10

Idee: Wenn wir beim Kopfknoten zwei Referenzen verfolgen können, sind die Teillisten kürzer. kopf Eine Datenstruktur mit Schlüsselwerten 1 bis 10 Binäre Bäume Bäume gehören zu den wichtigsten Datenstrukturen in der Informatik. Sie repräsentieren z.b. die Struktur eines arithmetischen Terms oder die Struktur eines Buchs. Bäume beschreiben Organisationshierarchien

Mehr

Algorithmen und Datenstrukturen Suchbaum

Algorithmen und Datenstrukturen Suchbaum Algorithmen und Datenstrukturen Suchbaum Matthias Teschner Graphische Datenverarbeitung Institut für Informatik Universität Freiburg SS 12 Motivation Datenstruktur zur Repräsentation dynamischer Mengen

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen Dipl. Inform. Andreas Wilkens aw@awilkens.com Überblick Grundlagen Definitionen Elementare Datenstrukturen Rekursionen Bäume 2 1 Datenstruktur Baum Definition eines Baumes

Mehr

Primzahlen und RSA-Verschlüsselung

Primzahlen und RSA-Verschlüsselung Primzahlen und RSA-Verschlüsselung Michael Fütterer und Jonathan Zachhuber 1 Einiges zu Primzahlen Ein paar Definitionen: Wir bezeichnen mit Z die Menge der positiven und negativen ganzen Zahlen, also

Mehr

368 4 Algorithmen und Datenstrukturen

368 4 Algorithmen und Datenstrukturen Kap04.fm Seite 368 Dienstag, 7. September 2010 1:51 13 368 4 Algorithmen und Datenstrukturen Java-Klassen Die ist die Klasse Object, ein Pfeil von Klasse A nach Klasse B bedeutet Bextends A, d.h. B ist

Mehr

17.1.2014 Einführung in die Programmierung Laborübung bei Korcan Y. Kirkici. 12.Übung 13.1. bis 17.1.2014

17.1.2014 Einführung in die Programmierung Laborübung bei Korcan Y. Kirkici. 12.Übung 13.1. bis 17.1.2014 17.1.2014 Einführung in die Programmierung Laborübung bei Korcan Y. Kirkici 12.Übung 13.1. bis 17.1.2014 1 BEFRAGUNG http://1.bp.blogspot.com/- waaowrew9gc/tuhgqro4u_i/aaaaaaaaaey/3xhl 4Va2SOQ/s1600/crying%2Bmeme.png

Mehr

Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung

Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung Anleitung zur Daten zur Datensicherung und Datenrücksicherung Datensicherung Es gibt drei Möglichkeiten der Datensicherung. Zwei davon sind in Ges eingebaut, die dritte ist eine manuelle Möglichkeit. In

Mehr

Programmierkurs Java

Programmierkurs Java Programmierkurs Java Dr. Dietrich Boles Aufgaben zu UE16-Rekursion (Stand 09.12.2011) Aufgabe 1: Implementieren Sie in Java ein Programm, das solange einzelne Zeichen vom Terminal einliest, bis ein #-Zeichen

Mehr

Datenstrukturen & Algorithmen

Datenstrukturen & Algorithmen Datenstrukturen & Algorithmen Matthias Zwicker Universität Bern Frühling 2010 Übersicht Binäre Suchbäume Einführung und Begriffe Binäre Suchbäume 2 Binäre Suchbäume Datenstruktur für dynamische Mengen

Mehr

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage: Zählen und Zahlbereiche Übungsblatt 1 1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage: Für alle m, n N gilt m + n = n + m. in den Satz umschreiben:

Mehr

1 Vom Problem zum Programm

1 Vom Problem zum Programm Hintergrundinformationen zur Vorlesung GRUNDLAGEN DER INFORMATIK I Studiengang Elektrotechnik WS 02/03 AG Betriebssysteme FB3 Kirsten Berkenkötter 1 Vom Problem zum Programm Aufgabenstellung analysieren

Mehr

Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012

Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012 WS 2011/2012 Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012 Prof. Dr. Robert Lorenz Musterlösung zur Vorlesung Informatik I, Extrablatt zu komplexen Datenstrukturen Aufgabe 45 **

Mehr

Hilfe zur Urlaubsplanung und Zeiterfassung

Hilfe zur Urlaubsplanung und Zeiterfassung Hilfe zur Urlaubsplanung und Zeiterfassung Urlaubs- und Arbeitsplanung: Mit der Urlaubs- und Arbeitsplanung kann jeder Mitarbeiter in Coffee seine Zeiten eintragen. Die Eintragung kann mit dem Status anfragen,

Mehr

Binärdarstellung von Fliesskommazahlen

Binärdarstellung von Fliesskommazahlen Binärdarstellung von Fliesskommazahlen 1. IEEE 754 Gleitkommazahl im Single-Format So sind in Gleitkommazahlen im IEEE 754-Standard aufgebaut: 31 30 24 23 0 S E E E E E E E E M M M M M M M M M M M M M

Mehr

icloud nicht neu, aber doch irgendwie anders

icloud nicht neu, aber doch irgendwie anders Kapitel 6 In diesem Kapitel zeigen wir Ihnen, welche Dienste die icloud beim Abgleich von Dateien und Informationen anbietet. Sie lernen icloud Drive kennen, den Fotostream, den icloud-schlüsselbund und

Mehr

13. Binäre Suchbäume

13. Binäre Suchbäume 1. Binäre Suchbäume Binäre Suchbäume realiesieren Wörterbücher. Sie unterstützen die Operationen 1. Einfügen (Insert) 2. Entfernen (Delete). Suchen (Search) 4. Maximum/Minimum-Suche 5. Vorgänger (Predecessor),

Mehr

Binäre Bäume Darstellung und Traversierung

Binäre Bäume Darstellung und Traversierung Binäre Bäume Darstellung und Traversierung Name Frank Bollwig Matrikel-Nr. 2770085 E-Mail fb641378@inf.tu-dresden.de Datum 15. November 2001 0. Vorbemerkungen... 3 1. Terminologie binärer Bäume... 4 2.

Mehr

Schritt 1 - Registrierung und Anmeldung

Schritt 1 - Registrierung und Anmeldung Schritt 1 - Registrierung und Anmeldung Anmeldung: Ihre Zugangsdaten haben Sie per EMail erhalten, bitte melden Sie sich mit diesen auf www.inthega-datenbank.de an. Bitte merken Sie sich die Zugangsdaten

Mehr

Vorkurs Informatik WiSe 15/16

Vorkurs Informatik WiSe 15/16 Konzepte der Informatik Dr. Werner Struckmann / Stephan Mielke, Jakob Garbe, 16.10.2015 Technische Universität Braunschweig, IPS Inhaltsverzeichnis Suchen Binärsuche Binäre Suchbäume 16.10.2015 Dr. Werner

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Serienbrief aus Outlook heraus Schritt 1 Zuerst sollten Sie die Kontakte einblenden, damit Ihnen der Seriendruck zur Verfügung steht. Schritt 2 Danach wählen Sie bitte Gerhard Grünholz 1 Schritt 3 Es öffnet

Mehr

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können.

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können. Tutorial: Wie erfasse ich einen Termin? In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können. Neben den allgemeinen Angaben zu einem

Mehr

infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock

infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock infach Ihr Weg zum finanzellen Erfolg Geld Florian Mock FBV Die Grundlagen für finanziellen Erfolg Denn Sie müssten anschließend wieder vom Gehaltskonto Rückzahlungen in Höhe der Entnahmen vornehmen, um

Mehr

Wie halte ich Ordnung auf meiner Festplatte?

Wie halte ich Ordnung auf meiner Festplatte? Wie halte ich Ordnung auf meiner Festplatte? Was hältst du von folgender Ordnung? Du hast zu Hause einen Schrank. Alles was dir im Wege ist, Zeitungen, Briefe, schmutzige Wäsche, Essensreste, Küchenabfälle,

Mehr

Tevalo Handbuch v 1.1 vom 10.11.2011

Tevalo Handbuch v 1.1 vom 10.11.2011 Tevalo Handbuch v 1.1 vom 10.11.2011 Inhalt Registrierung... 3 Kennwort vergessen... 3 Startseite nach dem Login... 4 Umfrage erstellen... 4 Fragebogen Vorschau... 7 Umfrage fertigstellen... 7 Öffentliche

Mehr

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang sysplus.ch outlook - mail-grundlagen Seite 1/8 Outlook Mail-Grundlagen Posteingang Es gibt verschiedene Möglichkeiten, um zum Posteingang zu gelangen. Man kann links im Outlook-Fenster auf die Schaltfläche

Mehr

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Objektorientierte Programmierung für Anfänger am Beispiel PHP Objektorientierte Programmierung für Anfänger am Beispiel PHP Johannes Mittendorfer http://jmittendorfer.hostingsociety.com 19. August 2012 Abstract Dieses Dokument soll die Vorteile der objektorientierten

Mehr

Anmerkungen zur Übergangsprüfung

Anmerkungen zur Übergangsprüfung DM11 Slide 1 Anmerkungen zur Übergangsprüfung Aufgabeneingrenzung Aufgaben des folgenden Typs werden wegen ihres Schwierigkeitsgrads oder wegen eines ungeeigneten fachlichen Schwerpunkts in der Übergangsprüfung

Mehr

Was meinen die Leute eigentlich mit: Grexit?

Was meinen die Leute eigentlich mit: Grexit? Was meinen die Leute eigentlich mit: Grexit? Grexit sind eigentlich 2 Wörter. 1. Griechenland 2. Exit Exit ist ein englisches Wort. Es bedeutet: Ausgang. Aber was haben diese 2 Sachen mit-einander zu tun?

Mehr

EINFACHES HAUSHALT- KASSABUCH

EINFACHES HAUSHALT- KASSABUCH EINFACHES HAUSHALT- KASSABUCH Arbeiten mit Excel Wir erstellen ein einfaches Kassabuch zur Führung einer Haushalts- oder Portokasse Roland Liebing, im November 2012 Eine einfache Haushalt-Buchhaltung (Kassabuch)

Mehr

5.2 Neue Projekte erstellen

5.2 Neue Projekte erstellen 5.2 Neue Projekte erstellen Das Bearbeiten von bestehenden Projekten und Objekten ist ja nicht schlecht wie aber können Sie neue Objekte hinzufügen oder gar völlig neue Projekte erstellen? Die Antwort

Mehr

Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER

Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER Abamsoft Finos in Verbindung mit der Webshopanbindung wurde speziell auf die Shop-Software shop to date von DATA BECKER abgestimmt. Mit

Mehr

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet C++ Grundlagen ++ bedeutet Erweiterung zum Ansi C Standard Hier wird eine Funktion eingeleitet Aufbau: In dieser Datei stehen die Befehle, die gestartet werden, wenn das Programm gestartet wird Int main()

Mehr

Leichte-Sprache-Bilder

Leichte-Sprache-Bilder Leichte-Sprache-Bilder Reinhild Kassing Information - So geht es 1. Bilder gucken 2. anmelden für Probe-Bilder 3. Bilder bestellen 4. Rechnung bezahlen 5. Bilder runterladen 6. neue Bilder vorschlagen

Mehr

Die Programmiersprache C99: Zusammenfassung

Die Programmiersprache C99: Zusammenfassung Die Programmiersprache C99: Zusammenfassung Jörn Loviscach Versionsstand: 7. Dezember 2010, 19:30 Die nummerierten Felder sind absichtlich leer, zum Ausfüllen in der Vorlesung. Videos dazu: http://www.youtube.com/joernloviscach

Mehr

Tutorial Speichern. Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 jroos@hispeed.ch - www.forums9.ch

Tutorial Speichern. Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 jroos@hispeed.ch - www.forums9.ch Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 jroos@hispeed.ch - www.forums9.ch Tutorial Speichern Wer ein Fotobuch zusammenstellen möchte, der sucht oft auf dem ganzen Computer und diversen

Mehr

Wir basteln einen Jahreskalender mit MS Excel.

Wir basteln einen Jahreskalender mit MS Excel. Wir basteln einen Jahreskalender mit MS Excel. In meinen Seminaren werde ich hin und wieder nach einem Excel-Jahreskalender gefragt. Im Internet findet man natürlich eine ganze Reihe mehr oder weniger

Mehr

Hilfe zur Dokumentenverwaltung

Hilfe zur Dokumentenverwaltung Hilfe zur Dokumentenverwaltung Die Dokumentenverwaltung von Coffee-CRM ist sehr mächtig und umfangreich, aber keine Angst die Bedienung ist kinderleicht. Im Gegensatz zur Foto Galeria können Dokumente

Mehr

Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book

Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book Wir wollen wissen wieviel Umsatz Vertreter Müller im Juni gemacht hat? Dazu klicken wir irgendwo in ein Feld und geben ein: =SVERWEIS

Mehr

Aufgabe: Knapp bei Kasse

Aufgabe: Knapp bei Kasse Bitte tragen Sie das heutige Datum ein: Anna und Beate unterhalten sich: Anna: Ich habe monatlich 250 Euro Taschengeld. Damit komme ich einfach nicht aus. Wieso das? 250 Euro sind doch viel Geld. Mein

Mehr

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny Grundlagen der Informatik Prof. Dr. Stefan Enderle NTA Isny 2 Datenstrukturen 2.1 Einführung Syntax: Definition einer formalen Grammatik, um Regeln einer formalen Sprache (Programmiersprache) festzulegen.

Mehr

Vorlesung Dokumentation und Datenbanken Klausur

Vorlesung Dokumentation und Datenbanken Klausur Dr. Stefan Brass 5. Februar 2002 Institut für Informatik Universität Giessen Vorlesung Dokumentation und Datenbanken Klausur Name: Geburtsdatum: Geburtsort: (Diese Daten werden zur Ausstellung des Leistungsnachweises

Mehr

Die Cloud der Gruppe Clubmädchen

Die Cloud der Gruppe Clubmädchen Die Cloud der Gruppe Clubmädchen Zuerst ein eigenes Google-Konto einrichten: Um die Cloud der Clubmädchen nutzen zu können, benötigen sie ein eigenes Google-Konto für welches eine Freigabe für die Clubmädchen-Cloud

Mehr

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7 Einrichtung des Cisco VPN Clients (IPSEC) in Windows7 Diese Verbindung muss einmalig eingerichtet werden und wird benötigt, um den Zugriff vom privaten Rechner oder der Workstation im Home Office über

Mehr

Partitionieren in Vista und Windows 7/8

Partitionieren in Vista und Windows 7/8 Partitionieren in Vista und Windows 7/8 Windows Vista und Windows 7 können von Haus aus Festplatten partitionieren. Doch die Funktion ist etwas schwer zu entdecken, denn sie heißt "Volume verkleinern".

Mehr

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1 Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1 Wenn der Name nicht gerade www.buch.de oder www.bmw.de heißt, sind Internetadressen oft schwer zu merken Deshalb ist es sinnvoll, die Adressen

Mehr

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter 2 Inhaltsverzeichnis 1 Web-Kürzel 4 1.1 Einführung.......................................... 4 1.2 Web-Kürzel.........................................

Mehr

Bedienungsanleitung für den Online-Shop

Bedienungsanleitung für den Online-Shop Hier sind die Produktgruppen zu finden. Zur Produktgruppe gibt es eine Besonderheit: - Seite 1 von 18 - Zuerst wählen Sie einen Drucker-Hersteller aus. Dann wählen Sie das entsprechende Drucker- Modell

Mehr

Zählen von Objekten einer bestimmten Klasse

Zählen von Objekten einer bestimmten Klasse Zählen von Objekten einer bestimmten Klasse Ziel, Inhalt Zur Übung versuchen wir eine Klasse zu schreiben, mit der es möglich ist Objekte einer bestimmten Klasse zu zählen. Wir werden den ++ und den --

Mehr

Summenbildung in Bauteiltabellen mit If Then Abfrage

Summenbildung in Bauteiltabellen mit If Then Abfrage Summenbildung in Bauteiltabellen mit If Then Abfrage Die in Bauteiltabellen ausgelesenen Werte lassen sich in jeder Spalte als Summe berechnen. So können selbstverständlich die Flächen der in der Tabelle

Mehr

«/Mehrere Umfragen in einer Umfrage durchführen» Anleitung

«/Mehrere Umfragen in einer Umfrage durchführen» Anleitung QuickStart «/Mehrere Umfragen in einer Umfrage durchführen» Anleitung Mehrere Umfragen in einer Umfrage durchführen Mögliches Szenario oder wann Sie davon Gebrauch machen können Sie führen regelmässig

Mehr

Andreas Rühl. Investmentfonds. verstehen und richtig nutzen. Strategien für die optimale Vermögensstruktur. FinanzBuch Verlag

Andreas Rühl. Investmentfonds. verstehen und richtig nutzen. Strategien für die optimale Vermögensstruktur. FinanzBuch Verlag Andreas Rühl Investmentfonds verstehen und richtig nutzen Strategien für die optimale Vermögensstruktur FinanzBuch Verlag 1. Kapitel Wollen Sie Millionär werden? Kennen Sie die Formel zur ersten Million?

Mehr

Anwendungsbeispiele Buchhaltung

Anwendungsbeispiele Buchhaltung Kostenstellen in Webling Webling ist ein Produkt der Firma: Inhaltsverzeichnis 1 Kostenstellen 1.1 Was sind Kostenstellen? 1.2 Kostenstellen in der 2 Kostenstellen in Webling 2.1 Kostenstellen erstellen

Mehr

Netzwerkeinstellungen unter Mac OS X

Netzwerkeinstellungen unter Mac OS X Netzwerkeinstellungen unter Mac OS X Dieses Dokument bezieht sich auf das D-Link Dokument Apple Kompatibilität und Problemlösungen und erklärt, wie Sie schnell und einfach ein Netzwerkprofil unter Mac

Mehr

Konzepte der Informatik

Konzepte der Informatik Konzepte der Informatik Vorkurs Informatik zum WS 2011/2012 26.09. - 30.09.2011 17.10. - 21.10.2011 Dr. Werner Struckmann / Christoph Peltz Stark angelehnt an Kapitel 1 aus "Abenteuer Informatik" von Jens

Mehr

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank In den ersten beiden Abschnitten (rbanken1.pdf und rbanken2.pdf) haben wir uns mit am Ende mysql beschäftigt und kennengelernt, wie man

Mehr

Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten

Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten Version 1.0 Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten In unserer Anleitung zeigen wir Dir, wie Du Blogbeiträge

Mehr

Kostenstellen verwalten. Tipps & Tricks

Kostenstellen verwalten. Tipps & Tricks Tipps & Tricks INHALT SEITE 1.1 Kostenstellen erstellen 3 13 1.3 Zugriffsberechtigungen überprüfen 30 2 1.1 Kostenstellen erstellen Mein Profil 3 1.1 Kostenstellen erstellen Kostenstelle(n) verwalten 4

Mehr

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten In dem Virtuellen Seminarordner werden für die Teilnehmerinnen und Teilnehmer des Seminars alle für das Seminar wichtigen Informationen,

Mehr

S/W mit PhotoLine. Inhaltsverzeichnis. PhotoLine

S/W mit PhotoLine. Inhaltsverzeichnis. PhotoLine PhotoLine S/W mit PhotoLine Erstellt mit Version 16.11 Ich liebe Schwarzweiß-Bilder und schaue mir neidisch die Meisterwerke an, die andere Fotografen zustande bringen. Schon lange versuche ich, auch so

Mehr

Handbuch. Adressen und Adressenpflege

Handbuch. Adressen und Adressenpflege Handbuch Adressen und Adressenpflege GateCom Informationstechnologie GmbH Am Glocketurm 6 26203 Wardenburg Tel. 04407 / 3141430 Fax: 04407 / 3141439 E-Mail: info@gatecom.de Support: www.gatecom.de/wiki

Mehr

Pages, Keynote. und Numbers

Pages, Keynote. und Numbers Pages, Keynote und Numbers Pages, Keynote und Numbers Die iwork-apps im Büro und unterwegs nutzen Mac und mehr. Numbers Tipps und Tricks zur Arbeit mit Tabellen Kapitel 18 Kapitel 18 Tabellen als Ganzes

Mehr

Austausch- bzw. Übergangsprozesse und Gleichgewichtsverteilungen

Austausch- bzw. Übergangsprozesse und Gleichgewichtsverteilungen Austausch- bzw. Übergangsrozesse und Gleichgewichtsverteilungen Wir betrachten ein System mit verschiedenen Zuständen, zwischen denen ein Austausch stattfinden kann. Etwa soziale Schichten in einer Gesellschaft:

Mehr

AZK 1- Freistil. Der Dialog "Arbeitszeitkonten" Grundsätzliches zum Dialog "Arbeitszeitkonten"

AZK 1- Freistil. Der Dialog Arbeitszeitkonten Grundsätzliches zum Dialog Arbeitszeitkonten AZK 1- Freistil Nur bei Bedarf werden dafür gekennzeichnete Lohnbestandteile (Stundenzahl und Stundensatz) zwischen dem aktuellen Bruttolohnjournal und dem AZK ausgetauscht. Das Ansparen und das Auszahlen

Mehr

Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte

Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte Klausur C-Programmierung / 15.02.2014 / Klingebiel / 60 Minuten / 60 Punkte Musterlösung 1. Aufgabe (5 Punkte) Im folgenden Programmcode sind einige Fehler enthalten. Finden und markieren Sie mindestens

Mehr

Erwin Grüner 09.02.2006

Erwin Grüner 09.02.2006 FB Psychologie Uni Marburg 09.02.2006 Themenübersicht Folgende Befehle stehen in R zur Verfügung: {}: Anweisungsblock if: Bedingte Anweisung switch: Fallunterscheidung repeat-schleife while-schleife for-schleife

Mehr

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst. 40-Tage-Wunder- Kurs Umarme, was Du nicht ändern kannst. Das sagt Wikipedia: Als Wunder (griechisch thauma) gilt umgangssprachlich ein Ereignis, dessen Zustandekommen man sich nicht erklären kann, so dass

Mehr

Name:... Vorname:... Matrikel-Nr.:... Unterschrift:...

Name:... Vorname:... Matrikel-Nr.:... Unterschrift:... Studiengang Bachelor of Computer Science Modulprüfung Praktische Informatik 1 Wintersemester 2010 / 2011 Name:... Vorname:... Matrikel-Nr.:... Unterschrift:... Hinweise: 1.) Schreiben Sie Ihren Namen und

Mehr

Teil 1: IT- und Medientechnik

Teil 1: IT- und Medientechnik Matrikelnummer Punkte Note Verwenden Sie nur dieses Klausurformular für Ihre Lösungen. Die Blätter müssen zusammengeheftet bleiben. Es dürfen keine Hilfsmittel oder Notizen in der Klausur verwendet werden

Mehr

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem Fachbericht zum Thema: Anforderungen an ein Datenbanksystem von André Franken 1 Inhaltsverzeichnis 1 Inhaltsverzeichnis 1 2 Einführung 2 2.1 Gründe für den Einsatz von DB-Systemen 2 2.2 Definition: Datenbank

Mehr

KONSTRUKTION VON ROT-SCHWARZ-BÄUMEN

KONSTRUKTION VON ROT-SCHWARZ-BÄUMEN KONSTRUKTION VON ROT-SCHWARZ-BÄUMEN RALF HINZE Institut für Informatik III Universität Bonn Email: ralf@informatik.uni-bonn.de Homepage: http://www.informatik.uni-bonn.de/~ralf Februar, 2001 Binäre Suchbäume

Mehr

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Dateiname: ecdl5_01_00_documentation_standard.doc Speicherdatum: 14.02.2005 ECDL 2003 Basic Modul 5 Datenbank - Grundlagen

Mehr

Zimmertypen. Zimmertypen anlegen

Zimmertypen. Zimmertypen anlegen Zimmertypen anlegen Hier legen Sie Ihre Zimmer an, damit sie auf der Homepage dargestellt werden und online buchbar gemacht werden können. Wobei wir ausdrücklich darauf hinweisen möchten, dass es ganz

Mehr

Erklärung zum Internet-Bestellschein

Erklärung zum Internet-Bestellschein Erklärung zum Internet-Bestellschein Herzlich Willkommen bei Modellbahnbau Reinhardt. Auf den nächsten Seiten wird Ihnen mit hilfreichen Bildern erklärt, wie Sie den Internet-Bestellschein ausfüllen und

Mehr

Handbuch ECDL 2003 Professional Modul 2: Tabellenkalkulation Vorlagen benutzen und ändern

Handbuch ECDL 2003 Professional Modul 2: Tabellenkalkulation Vorlagen benutzen und ändern Handbuch ECDL 2003 Professional Modul 2: Tabellenkalkulation Vorlagen benutzen und ändern Dateiname: ecdl_p2_02_03_documentation.doc Speicherdatum: 08.12.2004 ECDL 2003 Professional Modul 2 Tabellenkalkulation

Mehr

Funktionsbeschreibung. Lieferantenbewertung. von IT Consulting Kauka GmbH

Funktionsbeschreibung. Lieferantenbewertung. von IT Consulting Kauka GmbH Funktionsbeschreibung Lieferantenbewertung von IT Consulting Kauka GmbH Stand 16.02.2010 odul LBW Das Modul LBW... 3 1. Konfiguration... 4 1.1 ppm... 4 1.2 Zertifikate... 5 1.3 Reklamationsverhalten...

Mehr

Serienbrieferstellung in Word mit Kunden-Datenimport aus Excel

Serienbrieferstellung in Word mit Kunden-Datenimport aus Excel Sehr vielen Mitarbeitern fällt es schwer, Serienbriefe an Kunden zu verschicken, wenn sie die Serienbrieffunktion von Word nicht beherrschen. Wenn die Kunden mit Excel verwaltet werden, genügen nur ein

Mehr

Er musste so eingerichtet werden, dass das D-Laufwerk auf das E-Laufwerk gespiegelt

Er musste so eingerichtet werden, dass das D-Laufwerk auf das E-Laufwerk gespiegelt Inhaltsverzeichnis Aufgabe... 1 Allgemein... 1 Active Directory... 1 Konfiguration... 2 Benutzer erstellen... 3 Eigenes Verzeichnis erstellen... 3 Benutzerkonto erstellen... 3 Profil einrichten... 5 Berechtigungen

Mehr

How to install freesshd

How to install freesshd Enthaltene Funktionen - Installation - Benutzer anlegen - Verbindung testen How to install freesshd 1. Installation von freesshd - Falls noch nicht vorhanden, können Sie das Freeware Programm unter folgendem

Mehr

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Vollständigkeit halber aufgeführt. Gehen wir einmal davon aus, dass die von uns angenommenen 70% im Beispiel exakt berechnet sind. Was würde

Mehr

Lehrer: Einschreibemethoden

Lehrer: Einschreibemethoden Lehrer: Einschreibemethoden Einschreibemethoden Für die Einschreibung in Ihren Kurs gibt es unterschiedliche Methoden. Sie können die Schüler über die Liste eingeschriebene Nutzer Ihrem Kurs zuweisen oder

Mehr

Grundlagen der Theoretischen Informatik, SoSe 2008

Grundlagen der Theoretischen Informatik, SoSe 2008 1. Aufgabenblatt zur Vorlesung Grundlagen der Theoretischen Informatik, SoSe 2008 (Dr. Frank Hoffmann) Lösung von Manuel Jain und Benjamin Bortfeldt Aufgabe 2 Zustandsdiagramme (6 Punkte, wird korrigiert)

Mehr

Tutorial - www.root13.de

Tutorial - www.root13.de Tutorial - www.root13.de Netzwerk unter Linux einrichten (SuSE 7.0 oder höher) Inhaltsverzeichnis: - Netzwerk einrichten - Apache einrichten - einfaches FTP einrichten - GRUB einrichten Seite 1 Netzwerk

Mehr

Erstellen einer digitalen Signatur für Adobe-Formulare

Erstellen einer digitalen Signatur für Adobe-Formulare Erstellen einer digitalen Signatur für Adobe-Formulare (Hubert Straub 24.07.13) Die beiden Probleme beim Versenden digitaler Dokumente sind einmal die Prüfung der Authentizität des Absenders (was meist

Mehr

3.2 Binäre Suche. Usr/local/www/ifi/fk/menschen/schmid/folien/infovk.ppt 1

3.2 Binäre Suche. Usr/local/www/ifi/fk/menschen/schmid/folien/infovk.ppt 1 3.2 Binäre Suche Beispiel 6.5.1: Intervallschachtelung (oder binäre Suche) (Hier ist n die Anzahl der Elemente im Feld!) Ein Feld A: array (1..n) of Integer sei gegeben. Das Feld sei sortiert, d.h.: A(i)

Mehr

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Inhaltsverzeichnis 1. Anmeldung... 2 1.1 Startbildschirm... 3 2. Die PDF-Dateien hochladen... 4 2.1 Neue PDF-Datei erstellen... 5 3. Obelix-Datei

Mehr

Windows 7: Neue Funktionen im praktischen Einsatz - Die neue Taskleiste nutzen

Windows 7: Neue Funktionen im praktischen Einsatz - Die neue Taskleiste nutzen Windows 7: Neue Funktionen im praktischen Einsatz - Die neue Taskleiste nutzen Das können wir Ihnen versprechen: An der neuen Taskleiste in Windows 7 werden Sie sehr viel Freude haben. Denn diese sorgt

Mehr

Kommunikations-Management

Kommunikations-Management Tutorial: Wie kann ich E-Mails schreiben? Im vorliegenden Tutorial lernen Sie, wie Sie in myfactory E-Mails schreiben können. In myfactory können Sie jederzeit schnell und einfach E-Mails verfassen egal

Mehr

Guide DynDNS und Portforwarding

Guide DynDNS und Portforwarding Guide DynDNS und Portforwarding Allgemein Um Geräte im lokalen Netzwerk von überall aus über das Internet erreichen zu können, kommt man um die Themen Dynamik DNS (kurz DynDNS) und Portweiterleitung(auch

Mehr

Excel Pivot-Tabellen 2010 effektiv

Excel Pivot-Tabellen 2010 effektiv 7.2 Berechnete Felder Falls in der Datenquelle die Zahlen nicht in der Form vorliegen wie Sie diese benötigen, können Sie die gewünschten Ergebnisse mit Formeln berechnen. Dazu erzeugen Sie ein berechnetes

Mehr

Überblick. Lineares Suchen

Überblick. Lineares Suchen Komplexität Was ist das? Die Komplexität eines Algorithmus sei hierbei die Abschätzung des Aufwandes seiner Realisierung bzw. Berechnung auf einem Computer. Sie wird daher auch rechnerische Komplexität

Mehr