C++ – Ausführliche Informationen

C++-Sprachanleitung

In den ersten Abschnitten dieser Anleitung wird das Grundmaterial behandelt, das bereits in den letzten beiden Modulen behandelt wurde. Außerdem finden Sie dort weitere Informationen zu erweiterten Konzepten. In diesem Modul konzentrieren wir uns auf dynamischen Speicher und weitere Details zu Objekten und Klassen. Es werden auch einige erweiterte Themen vorgestellt, z. B. Vererbung, Polymorphie, Vorlagen, Ausnahmen und Namespaces. Wir werden diese später im C++-Kurs für Fortgeschrittene beschäftigen.

Objektorientiertes Design

Dies ist ein hervorragendes Tutorial für objektorientiertes Design. Wir wenden die hier vorgestellte Methodik im Projekt dieses Moduls an.

Lernen anhand von Beispiel 3

In diesem Modul konzentrieren wir uns darauf, mehr Übung mit Pointern, objektorientiertem Design, mehrdimensionalen Arrays und Klassen/Objekten zu sammeln. Gehen Sie die folgenden Beispiele durch. Wir können gar nicht genug betonen, dass der Schlüssel zu einem guten Programmierer im Üben, Üben und Üben liegt.

Übung 1: Mehr Übung mit Mauszeigern

Wenn Sie weitere Übungen mit Cursor benötigen, lesen Sie diese Ressource, die alle Aspekte von Cursors abdeckt und viele Programmbeispiele enthält.

Wie sieht das Ergebnis des folgenden Programms aus? Führen Sie das Programm nicht aus, sondern zeichnen Sie das Speicherbild, um die Ausgabe zu ermitteln.

void Unknown(int *p, int num);
void HardToFollow(int *p, int q, int *num);

void Unknown(int *p, int num) {
  int *q;

  q = #
  *p = *q + 2;
  num = 7;
}

void HardToFollow(int *p, int q, int *num) {
  *p = q + *num;
  *num = q;
  num = p;
  p = &q;
  Unknown(num, *p);
}

main() {
  int *q;
  int trouble[3];

  trouble[0] = 1;
  q = &trouble[1];
  *q = 2;
  trouble[2] = 3;

  HardToFollow(q, trouble[0], &trouble[2]);
  Unknown(&trouble[0], *q);

  cout << *q << " " << trouble[0] << " " << trouble[2];
}

Nachdem Sie die Ausgabe manuell ermittelt haben, führen Sie das Programm aus, um zu sehen, ob Sie richtig liegen.

Übung 2: Mehr Übung mit Klassen und Objekten

Wenn Sie zusätzliche Übung im Umgang mit Klassen und Objekten benötigen, finden Sie hier eine Ressource, die die Implementierung von zwei kleinen Klassen durchläuft. Nehmen Sie sich etwas Zeit für die Übungen.

Übung 3: Mehrdimensionale Arrays

Ziehen Sie das folgende Programm in Betracht: 

const int kStudents = 25;
const int kProblemSets = 10;

// This function returns the highest grade in the Problem Set array.
int get_high_grade(int *a, int cols, int row, int col) {
  int i, j;
  int highgrade = *a;

  for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
      if (*(a + i * cols + j) > highgrade)  // How does this line work?
        highgrade = *(a + i*cols + j);
  return highgrade;
}

int main() {
 int grades[kStudents][kProblemSets] = {
   {75, 70, 85, 72, 84},
   {85, 92, 93, 96, 86},
   {95, 90, 83, 76, 97},
   {65, 62, 73, 84, 73}
 };
 int std_num = 4;
 int ps_num = 5;
 int highest;

 highest = get_high_grade((int *)grades, kProblemSets, std_num, ps_num);
 cout << "The highest problem set score in the class is " << highest << endl;

 return 0;
}

In diesem Programm gibt es eine Zeile mit der Bezeichnung „Wie funktioniert diese Linie?“. - finden Sie es heraus? Hier finden Sie unsere Erklärung.

Schreiben Sie ein Programm, das ein dreidimensionales Array initialisiert und den Wert der dritten Dimension mit der Summe aller drei Indexe füllt. Hier finden Sie unsere Lösung.

Übung 4: Umfangreiches Designbeispiel für OO

Hier ist ein detailliertes objektorientiertes Designbeispiel, das den gesamten Prozess von Anfang bis Ende durchläuft. Der endgültige Code ist in der Programmiersprache Java geschrieben, lässt sich aber gut lesen, wenn Sie den Fortschritt erfahren.

Bitte nehmen Sie sich die Zeit, das gesamte Beispiel durchzugehen. Es ist eine tolle Darstellung des Prozesses und der Designtools, die ihn unterstützen.

Einheitentest

Einführung

Tests sind ein wichtiger Teil des Softwareentwicklungsprozesses. Ein Einheitentest ist eine bestimmte Art von Test, mit dem die Funktionalität eines einzelnen, kleinen Moduls des Quellcodes geprüft wird.Einheitentests werden immer vom Entwickler durchgeführt und in der Regel gleichzeitig mit der Codierung des Moduls. Die Testtreiber, die Sie zum Testen der Composer- und Database-Klassen verwendet haben, sind Beispiele für Einheitentests.

Einheitentests haben die folgenden Eigenschaften. Sie...

  • eine Komponente isoliert testen
  • sind deterministisch
  • in der Regel einer einzelnen Klasse
  • Vermeiden Sie Abhängigkeiten von externen Ressourcen wie Datenbanken, Dateien, Netzwerke
  • schnell umsetzen
  • können in beliebiger Reihenfolge ausgeführt werden

Es gibt automatisierte Frameworks und Methoden, die bei Einheitentests in großen Softwareentwicklungsunternehmen Unterstützung und Konsistenz bieten. Es gibt einige ausgefeilte Frameworks für Open-Source-Einheitentests, auf die wir später in dieser Lektion noch näher eingehen werden. 

Die Tests, die im Rahmen von Einheitentests durchgeführt werden, sind unten dargestellt.

Im Idealfall testen wir Folgendes:

  1. Die Modulschnittstelle wird getestet, um sicherzustellen, dass Informationen korrekt ein- und gesendet werden.
  2. Lokale Datenstrukturen werden untersucht, um sicherzustellen, dass sie Daten ordnungsgemäß speichern.
  3. Begrenzungsbedingungen werden getestet, um sicherzustellen, dass das Modul an den Grenzen, die die Verarbeitung einschränken oder einschränken, ordnungsgemäß funktioniert.
  4. Wir testen unabhängige Pfade im Modul, um sicherzustellen, dass jeder Pfad und damit jede Anweisung im Modul mindestens einmal ausgeführt wird. 
  5. Schließlich müssen wir überprüfen, ob Fehler ordnungsgemäß behandelt werden.

Codeabdeckung

In Wirklichkeit können wir mit unseren Tests keine vollständige Codeabdeckung erreichen. Die Codeabdeckung ist eine Analysemethode, die bestimmt, welche Teile eines Softwaresystems von der Testlaufsuite ausgeführt (abgedeckt) und welche nicht ausgeführt wurden. Wenn wir versuchen, eine Abdeckung von 100% zu erreichen, verbringen wir mehr Zeit mit dem Schreiben von Einheitentests als mit dem Schreiben des eigentlichen Codes. Erwägen Sie die Entwicklung von Einheitentests für alle unabhängigen Pfade der folgenden Elemente. Dies kann schnell zu einem exponentiellen Problem werden.

In diesem Diagramm werden die roten Linien nicht getestet, während die nicht farbigen Linien getestet werden.

Anstatt eine Abdeckung von 100% zu erreichen, konzentrieren wir uns auf Tests, mit denen wir uns darauf verlassen können, dass das Modul ordnungsgemäß funktioniert. Wir testen u. a. auf Folgendes:

  • Null-Fälle
  • Bereichstests (z.B. positive/negative Werte)
  • Sonderfälle
  • Fehlerfälle
  • Pfade testen, die wahrscheinlich am häufigsten ausgeführt werden

Frameworks für Einheitentests

Die meisten Einheitentest-Frameworks verwenden Assertions, um Werte während der Ausführung eines Pfades zu testen. Assertions sind Anweisungen, mit denen geprüft wird, ob eine Bedingung erfüllt ist. Das Ergebnis einer Assertion kann ein Erfolg, ein nicht schwerwiegender Fehler oder ein schwerwiegender Fehler sein. Nachdem eine Assertion ausgeführt wurde, wird das Programm normal fortgesetzt, wenn das Ergebnis entweder ein Erfolg oder ein nicht schwerwiegender Fehler ist. Bei einem schwerwiegenden Fehler wird die aktuelle Funktion abgebrochen.

Tests bestehen aus Code, mit dem der Status eingerichtet oder das Modul manipuliert wird. Außerdem wird eine Reihe von Assertions verwendet, die die erwarteten Ergebnisse verifizieren. Wenn alle Assertions in einem Test erfolgreich sind, d. h. „true“ zurückgeben, ist der Test erfolgreich. Andernfalls schlägt er fehl.

Ein Testlauf enthält einen oder mehrere Tests. Wir gruppieren Tests zu Testläufen, die die Struktur des getesteten Codes widerspiegeln. In diesem Kurs verwenden wir CPPUnit als Framework für Einheitentests. Mit diesem Framework können wir Einheitentests in C++ schreiben und automatisch ausführen, um einen Bericht über den Erfolg oder Misserfolg der Tests zu erhalten.

CPPUnit-Installation

Laden Sie den CPPUnit-Code von SourceForge herunter. Suchen Sie ein geeignetes Verzeichnis und speichern Sie dort die Datei tar.gz. Geben Sie dann die folgenden Befehle ein (in Linux, Unix) und ersetzen Sie den entsprechenden cppunit-Dateinamen:

gunzip filename.tar.gz
tar -xvf filename.tar

Wenn Sie unter Windows arbeiten, benötigen Sie möglicherweise ein Dienstprogramm zum Extrahieren von tar.gz-Dateien. Im nächsten Schritt müssen die Bibliotheken kompiliert werden. Wechseln Sie in das Verzeichnis „cppunit“. Dort gibt es eine INSTALL-Datei, die spezifische Anweisungen enthält. Normalerweise müssen Sie Folgendes ausführen:

./configure
make install

Falls Probleme auftreten, schlagen Sie in der INSTALL-Datei nach. Die Bibliotheken befinden sich normalerweise im Verzeichnis „cppunit/src/cppunit“. Wenn Sie prüfen möchten, ob die Kompilierung funktioniert hat, rufen Sie das Verzeichnis „cppunit/examples/simple“ auf und geben Sie „make“ ein. Wenn alles in Ordnung ist, sind Sie startklar.

Hier finden Sie ein hervorragendes Tutorial. Gehen Sie diese Anleitung durch und erstellen Sie die komplexe Zahlenklasse und die zugehörigen Einheitentests. Das Verzeichnis cppunit/examples enthält einige weitere Beispiele.

Warum muss ich das tun???

Einheitentests sind in der Branche aus mehreren Gründen von entscheidender Bedeutung. Sie kennen bereits einen Grund: Wir müssen unsere Arbeit während der Codeentwicklung überprüfen. Selbst wenn wir ein sehr kleines Programm entwickeln, schreiben wir instinktiv eine Art Checker oder Treiber, um sicherzustellen, dass unser Programm das tut, was wir erwarten.

Aus langjähriger Erfahrung wissen Entwickler, dass die Chancen, dass ein Programm beim ersten Versuch funktioniert, sehr gering ist. Unittests bauen auf dieser Idee auf und machen Testprogramme selbstüberprüfbar und wiederholbar. Die Assertions ersetzen die manuelle Überprüfung der Ausgabe. Da die Ergebnisse einfach zu interpretieren sind (der Test besteht oder schlägt fehl), können die Tests immer wieder ausgeführt werden und bieten ein Sicherheitsnetz, das Ihren Code weniger anfällig für Änderungen macht.

Lassen Sie uns dies konkret formulieren: Wenn Sie Ihren fertigen Code zum ersten Mal an CVS senden, funktioniert er einwandfrei. Und es funktioniert noch eine Zeit lang einwandfrei. Eines Tages ändert dann eine andere Person Ihren Code. Früher oder später wird Ihr Code beschädigt. Glauben Sie, dass sie es von selbst merken? Das ist unwahrscheinlich. Wenn Sie jedoch Einheitentests schreiben, gibt es Systeme, die diese automatisch jeden Tag ausführen können. Diese werden als Continuous Integration-Systeme bezeichnet. Wenn dieser Entwickler X also Ihren Code bricht, sendet das System ihm unschöne E-Mails, bis er das Problem behoben hat. Auch wenn Sie als Entwickler X selbst tätig sind

Einheitentests unterstützen Sie nicht nur bei der Softwareentwicklung und dem Schutz dieser Software bei Änderungen:

  • Erstellt eine ausführbare Spezifikation und eine Dokumentation, die mit dem Code synchronisiert bleibt. Mit anderen Worten, Sie können einen Einheitentest lesen, um zu erfahren, welches Verhalten das Modul unterstützt.
  • Hilft Ihnen, Anforderungen von der Implementierung zu trennen. Da Sie extern sichtbares Verhalten geltend machen, haben Sie die Möglichkeit, explizit darüber nachzudenken, anstatt Ideen zur Implementierung des Verhaltens einfließen zu lassen.
  • Unterstützt Experimente. Wenn Sie ein Sicherheitsnetz haben, über das Sie informiert werden, wenn Sie das Verhalten eines Moduls beschädigt haben, ist es wahrscheinlicher, dass Sie Dinge ausprobieren und Ihre Designs neu konfigurieren.
  • Verbessert Ihre Designs. Beim Schreiben gründlicher Einheitentests müssen Sie den Code häufig testbarer gestalten. Testbarer Code ist oft modularer als nicht testbarer Code.
  • Hohe Qualität Ein kleiner Fehler in einem kritischen System kann dazu führen, dass ein Unternehmen Millionen von Dollar oder noch schlimmer, die Zufriedenheit und das Vertrauen eines Nutzers verlieren. Das Sicherheitsnetz, das Einheitentests bieten, verringert diese Möglichkeit. Da Fehler frühzeitig erkannt werden, können QA-Teams sich auf komplexere und schwierigere Fehlerszenarien konzentrieren, anstatt offensichtliche Fehler zu melden.

Nehmen Sie sich etwas Zeit, um Einheitentests mit CPPUnit für die Composer-Datenbankanwendung zu schreiben. Weitere Informationen finden Sie im Verzeichnis „cppunit/examples/“.

Wie Google tickt – How Google Works

Einführung

Stellen Sie sich einen Mönch im Mittelalter vor, der sich in den Archiven seines Klosters Tausende von Manuskripten ansieht.„Where is that one by Aristoteles...“

klosterbibliothek

Glücklicherweise sind die Manuskripte nach Inhalt geordnet und mit speziellen Symbolen versehen, damit die darin enthaltenen Informationen leichter abgerufen werden können. Ohne eine solche Organisation wäre es sehr schwierig, das relevante Manuskript zu finden.

Das Speichern und Abrufen geschriebener Informationen aus großen Sammlungen wird als Information Retrieval (IR) bezeichnet. Diese Aktivität gewinnt im Laufe der Jahrhunderte immer mehr an Bedeutung, insbesondere bei Erfindungen wie Papier und Druckerei. Früher waren nur wenige Menschen dort beschäftigt. Heutzutage rufen jedoch täglich Hunderte Millionen Menschen Informationen ab, wenn sie eine Suchmaschine verwenden oder auf ihrem Computer eine Suche durchführen.

Erste Schritte beim Informationsabruf

Katze im Hut

Dr. Seuss hat innerhalb von 30 Jahren 46 Kinderbücher verfasst. In seinen Büchern erzählt er von Katzen, Kühen und Elefanten, wer ist da, grinst und dem Lorax. Weißt du noch, welche Lebewesen in welcher Geschichte zu finden waren? Wenn Sie kein Elternteil sind, können nur Kinder Ihnen sagen, welche Erzählungen von Dr. Seuss die Lebewesen enthalten:

(COW und BEE) oder CROWS

Wir werden einige klassische Informationsabrufmodelle anwenden, um dieses Problem zu lösen.

Ein offensichtlicher Ansatz ist Brute-Force: Rufen Sie alle 46 Geschichten von Dr. Seuss auf und beginnen Sie mit dem Lesen. Notieren Sie sich für jedes Buch, welches die Wörter COW und BEE enthält, und suchen Sie gleichzeitig nach Büchern, die das Wort CROWS enthalten. Computer sind in dieser Zeit viel schneller als wir. Wenn wir den gesamten Text aus den Büchern von Dr. Seuss in digitaler Form haben, z. B. als Textdateien, können wir die Dateien einfach mit grep durchgehen. Bei einer kleinen Sammlung wie den Büchern von Dr. Seuss eignet sich diese Technik gut.

Es gibt jedoch viele Situationen, in denen wir mehr brauchen. Zum Beispiel ist die Erhebung aller derzeit online verfügbaren Daten viel zu groß, um grep zu verarbeiten. Außerdem möchten wir nicht nur die Dokumente, die unseren Zustand erfüllen, sondern wir haben es gewohnt, sie nach ihrer Relevanz sortieren zu lassen.

Neben grep können Sie auch vor der Suche einen Index der Dokumente in einer Sammlung erstellen. Ein Index in IR ähnelt einem Index am Ende eines Lehrbuchs. Wir erstellen eine Liste aller Wörter (oder Begriffe) in jeder Dr. Seuss-Geschichte und lassen Wörter wie „das“, „und“ sowie andere Verbindungen, Präpositionen usw. aus (diese werden als Stoppwörter bezeichnet). Diese Informationen werden dann so dargestellt, dass es leichter ist, die Begriffe zu finden und die Meldungen zu identifizieren, in denen sie vorkommen.

Eine mögliche Darstellung ist eine Matrix mit den Artikeln oben und den Begriffen in jeder Zeile. Eine „1“ in einer Spalte bedeutet, dass der Begriff in der Abfolge für diese Spalte vorkommt.

Tabelle mit Büchern und Wörtern

Wir können jede Zeile oder Spalte als Bitvektor betrachten. Der Bitvektor einer Zeile gibt an, in welchen Geschichten der Begriff vorkommt. Der Bitvektor einer Spalte gibt an, welche Begriffe in der Geschichte vorkommen.

Zurück zu unserem ursprünglichen Problem:

(COW und BEE) oder CROWS

Wir nehmen die Bitvektoren für diese Begriffe und führen zuerst ein bitweises UND und dann ein bitweises OR für das Ergebnis durch.

(100001 und 010011) oder 000010 = 000011

Die Antwort: „Herr Braun kann Moo! Kannst du das?“ und „Der Lorax“. Dies ist eine Illustration des Booleschen Abrufmodells, bei dem es sich um ein Modell der exakten Übereinstimmung handelt.

Angenommen, wir möchten die Matrix erweitern, um alle Geschichten von Dr. Seuss und alle relevanten Begriffe darin aufzunehmen. Die Matrix würde erheblich wachsen und eine wichtige Beobachtung ist, dass die meisten Einträge 0 sind. Eine Matrix ist wahrscheinlich nicht die beste Darstellung für den Index. Wir müssen eine Möglichkeit finden, nur die Einsen zu speichern.

Einige Verbesserungen

Die Struktur, die in der Infraroteinheit zur Lösung dieses Problems verwendet wird, wird als umgekehrter Index bezeichnet. Wir führen ein Wörterbuch mit Begriffen. Für jeden Begriff führen wir eine Liste mit den Dokumenten auf, in denen der Begriff vorkommt. Diese Liste wird als Posting-Liste bezeichnet. Eine einfach verknüpfte Liste eignet sich gut, um diese Struktur wie unten dargestellt darzustellen.

Wenn Sie nicht mit verknüpften Listen vertraut sind, suchen Sie einfach in Google nach „verknüpfte Liste in C++“. Dort finden Sie viele Ressourcen, in denen das Erstellen von Listen und ihre Verwendung beschrieben werden. Darauf gehen wir in einem späteren Modul genauer ein.

Anstelle des Namens der Geschichte verwenden wir Dokument-IDs (DocIDs). Wir sortieren auch diese DocIDs, da dies die Verarbeitung von Abfragen erleichtert.

Wie verarbeiten wir eine Abfrage? Für das ursprüngliche Problem suchen wir zuerst die Liste der COW-Veröffentlichungen, dann die Liste der BEE-Beiträge. Anschließend führen wir sie zusammen:

  1. Speichern Sie Markierungen in beiden Listen und gehen Sie die beiden Listen mit Stellenangeboten gleichzeitig durch.
  2. Vergleichen Sie bei jedem Schritt die Dokument-ID, auf die beide Zeiger zeigen.
  3. Wenn sie identisch sind, fügen Sie die DocID in eine Ergebnisliste ein. Ansonsten setzen Sie den Zeiger weiter, der auf die kleinere docID verweist.

So können wir einen invertierten Index erstellen:

  1. Weisen Sie jedem gewünschten Dokument eine DocID zu.
  2. Identifizieren Sie für jedes Dokument die relevanten Begriffe (Tokenisieren).
  3. Erstellen Sie für jeden Begriff einen Datensatz, der aus dem Begriff, der DocID, unter der er gefunden wird, und einer Häufigkeit in diesem Dokument besteht. Es kann mehrere Einträge für einen bestimmten Begriff geben, wenn er in mehr als einem Dokument vorkommt.
  4. Sortieren Sie die Datensätze nach Begriff.
  5. Erstellen Sie das Wörterbuch und die Posting-Liste, indem Sie einzelne Datensätze für einen Begriff verarbeiten und die Datensätze für Begriffe, die in mehreren Dokumenten vorkommen, kombinieren. Erstellen Sie eine verknüpfte Liste der DocIDs (in sortierter Reihenfolge). Jeder Term hat auch eine Frequenz, d. h. die Summe der Häufigkeiten in allen Datensätzen eines Begriffs.

Das Projekt

Suchen Sie nach mehreren umfangreichen Klartextdokumenten, mit denen Sie experimentieren können. Im Rahmen des Projekts wird mit den oben beschriebenen Algorithmen ein umgekehrter Index aus den Dokumenten erstellt. Außerdem müssen Sie eine Schnittstelle für die Eingabe von Abfragen und eine Engine für deren Verarbeitung erstellen. Im Forum können Sie nach Projektpartnern suchen.

Hier ist ein mögliches Verfahren zur Fertigstellung dieses Projekts:

  1. Zunächst müssen Sie eine Strategie für die Identifizierung von Begriffen in den Dokumenten definieren. Erstellen Sie eine Liste aller Stoppwörter, die Ihnen einfallen, und schreiben Sie eine Funktion, die die Wörter in den Dateien liest, die Begriffe speichert und die Stoppwörter löscht. Möglicherweise müssen Sie Ihrer Liste weitere Stoppwörter hinzufügen, wenn Sie die Liste der Begriffe aus einer Iteration prüfen.
  2. Schreiben Sie CPPUnit-Testfälle, um Ihre Funktion zu testen, und ein Makefile, um alles für Ihren Build zusammenzuführen. Checken Sie Ihre Dateien in das CSVS-Format ein, insbesondere wenn Sie mit Partnern zusammenarbeiten. Informieren Sie sich darüber, wie Sie Ihre CVS-Instanz für Remote-Entwickler zugänglich machen können.
  3. Fügen Sie die Verarbeitung hinzu, um Standortdaten einzubeziehen. Das heißt, welche Datei und wo in der Datei befindet sich ein Begriff? Vielleicht möchten Sie eine Berechnung durchführen, um die Seiten- oder Absatznummer zu definieren.
  4. Schreiben Sie CPPUnit-Testfälle, um diese zusätzliche Funktionalität zu testen.
  5. Erstellen Sie einen umgekehrten Index und speichern Sie die Standortdaten im Datensatz jedes Begriffs.
  6. Mehr Testläufe schreiben
  7. Entwerfen Sie eine Oberfläche, in der Nutzende eine Abfrage eingeben können.
  8. Verwenden Sie den oben beschriebenen Suchalgorithmus, um den umgekehrten Index zu verarbeiten und die Standortdaten an den Nutzer zurückzugeben.
  9. Vergessen Sie nicht, auch Testfälle für diesen letzten Teil anzugeben.

Wie bei allen Projekten können Sie das Forum und den Chat nutzen, um Projektpartner zu finden und Ideen auszutauschen.

Eine Zusatzfunktion

Ein häufiger Verarbeitungsschritt in vielen IR-Systemen wird als Steming bezeichnet. Die Hauptidee des Wortstamms besteht darin, dass Nutzer, die nach Informationen zum „Abrufen“ suchen, auch an Dokumenten interessiert sind, die Informationen enthalten, die „abrufen“, „abgerufen“, „abrufen“ usw. enthalten. Systeme können aufgrund von schlechtem Wortstamm anfällig für Fehler sein, daher ist dies etwas kompliziert. Einem Nutzer, der sich für den Informationsabruf interessiert, könnte beispielsweise ein Dokument mit dem Titel „Informationen über Golden Retriever“ angezeigt werden, weil es die Wortstammfunktion verwendet. Ein nützlicher Algorithmus für die Wortstammerkennung ist der Porter-Algorithmus.

Anwendung: Überall hin!

Diese Konzepte können Sie unter Panoramas.dk anwenden.