10.07.2015 Aufrufe

Übung 2 Textsuche

Übung 2 Textsuche

Übung 2 Textsuche

MEHR ANZEIGEN
WENIGER ANZEIGEN
  • Keine Tags gefunden...

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Algorithmen und Datenstrukturen 1Prof. Dr. C. Stamm christoph.stamm@fhnw.ch Tel.: 056 462 47 44Übung 2 <strong>Textsuche</strong>1.1 EinleitungDas Suchen von Buchstabenfolgen in Texten ist heute eine häufige Aufgabe. In einem langen Text(z.B. auf Homepages) wird meistens nach einem Stichwort gesucht. So muss nicht das ganze Dokumentüberflogen werden, um die interessante Passage zu finden.Um diese Aufgabe zu erfüllen wird die Stringsuche verwendet. Für die Stringsuche gibt es sehr vieleAlgorithmen. Aus Zeitmangel kann hier jedoch nur ein kleiner Einblick in dieses Thema gewährt werden.Zum Einstieg wird das naive Verfahren vorgestellt. Danach wird der Algorithmus von Knuth-Morris-Pratt (KMP) erklärt. Moderne Intel-Prozessoren bieten spezielle SIMD-Befehle (Single InstructionMultiple Data) für die schnelle <strong>Textsuche</strong> nach dem KMP-Verfahren an.1.2 Naives VerfahrenDieses Verfahren wird auch Brute Force (Suchen einer Lösung durch Ausprobieren aller Varianten)Verfahren genannt. Wir werden im Folgenden die zu suchende Buchstabenfolge als Pattern bezeichnen.Der Text in dem gesucht wird, wird als Text bezeichnet.1.2.1 PrinzipDas Prinzip dieses Algorithmus ist ganz simpel. Verwendet wird ein Zeiger, der auf die aktuelle Positionim Text verweist.1. Setze den Textzeiger auf den ersten Buchstaben des Textes.2. Prüfe, ob an dieser Position das gesuchte Pattern anfängt.3. Wenn nicht, schiebe den Textzeiger nach rechts. Gehe zu 2.4. Falls der Text zu Ende ist, stoppe.Beispiel: im Text „baabcabac“ wird nach dem Pattern „bac“ gesucht.b a a b c a b a cb a cb a cb a cb a cb a cb a cb a cDie umrahmten Buchstaben zeigen an bei welchem Vergleich ein Fehler aufgetreten ist. Danach wirddas Pattern nach rechts verschoben. Ganz am Ende wird das Pattern dann gefunden.1


1.2.2 ImplementierungDieses Verfahren ist ganz einfach zu implementieren. Hier ist der Pseudocode dafür angegeben.BruteForce (String text, String pattern){}int zeiger := 0while (zeiger noch nicht am Ende des Textes – Länge des Patterns){// Vergleiche den Textausschnitt mit dem Patternint i := zeigerint j := 0while ( j < Länge des Patterns UND text[i] == pattern[j]){}j++i++if (j == Länge des Patterns){}Pattern im Text gefundenzeiger eins nach rechts verschiebenAufgabe 1Implementieren Sie diesen Suchalgorithmus.Aufgabe 2Was ist die Laufzeit dieses Algorithmus?1.3 Knuth-Morris-Pratt (KMP)Wenn ein Teil des Textes mit dem Pattern übereinstimmt, dann wird diese Information im naivenVerfahren nicht weiterverwendet. Wenn Sie z.B. wissen, dass in Ihrem Pattern alle Buchstaben nureinmal auftreten, dann können Sie bei einem Missmatch gleich dort weitermachen, wo der Missmatchaufgetaucht ist.Beispiel: Das Pattern „bac“ enthält keinen Buchstaben zwei Mal. Die Suche wird im Text „babaabac“ausgeführt.b a b a a b a cb a cb a cb a cb a cDer Algorithmus von Knuth-Morris-Pratt verwendet für die Suche zusätzliche Informationen über dasPattern. Das Ziel dabei ist, das Pattern möglichst weit nach rechts zu verschieben, ohne dass einVorkommen übersehen wird.1.3.1 IdeeAls erstes wird beim KMP das zu suchende Pattern untersucht. Das Pattern wird mit sich selberverglichen. Das Ziel ist zu wissen, bei welchem Buchstaben des Patterns man bei einem Missmatchweitermachen soll.Beispiel: „haushalt“h a u s h a l th a u s h a l tWenn hier beim Vergleichen mit dem Text beim „l“ ein Fehler auftritt, dann kann der Vergleich beim„u“ weitergeführt werden, da die Buchstabenfolge „ha“ am Anfang genau der Buchstabenfolge „ha“ inder Mitte des Wortes entspricht.Es wird also für jedes Teilstück des Patterns das Endstück maximaler Länge gesucht, welches einemAnfangsstück entspricht. Dann wird abgespeichert, wo mit dem Vergleichen fortgefahren werdenmuss, wenn an dieser Stelle ein Fehler auftritt.2


0 1 2 3 4 5 6 7h a u s h a l t-1 0 0 0 0 1 2 0Die Tabelle Zeigt die Verschiebeinformationen für das Beispiel. Wenn beim Vergleich der Position 5mit dem Text ein Fehler auftritt, dann muss bei Position 1 (also 1 wieder verglichen werden). Nur fürden Anfangsbuchstaben ist der Wert -1. Wenn dieser genommen wird, heisst das, dass das Patternwieder von vorne verglichen werden muss.Diese Verschiebeinformationen werden zu Beginn der Suche im Text berechnet. Damit muss bei derSuche nie ein Teilstück zweimal durchsucht werden.1.3.2 Prinzip (Verschiebetabelle)Das folgende Prinzip berechnet die Verschiebeinformation:1. Es gibt zwei Zeiger i und j. i wird das Pattern einmal ganz durchlaufen. j springt immer dannwieder zum Anfang des Patterns, wenn ein Missmatch auftritt. j wird zu Beginn auf den Wert -1 gesetzt, i auf den Wert 0.2. Setze für den ersten Wert in der Tabelle -1.3. Überprüfe, ob j kleiner 0 ist oder ob die Buchstaben bei i und j gleich sind.a. Ist dies der Fall, inkrementiere i und j. Speichere anschliessend den Wert von j an derPosition i in der Tabelle.b. Ist dies nicht der Fall, setze j auf den Wert an der Stelle j in der Tabelle.4. Gehe wieder zu 3.5. Wenn i das Patternende erreicht hat stoppe.Aufgabe 3Vergleichen Sie die folgenden Wörter mit sich selber und erstellen Sie die Verschiebetabelle:„rosarot“; „eber“; „kakadu“Aufgabe 4Schreiben Sie eine Methode initnext(), gemäss Pseudocode, die die Tabelle für Sie berechnet.Halten Sie sich dabei an die folgenden Vorgaben.Die Klasse heisst KPM. Die Verschiebeinformation wird im Array next gespeichert. Dieses Array sollein Parameter der Klasse KPM sein. Auch das Pattern soll ein Parameter der Klasse sein. Er wird alsArray von char gespeichert.Pseudocode:public void initnext(){// verwende zwei Zähler i und j// i wird das Pattern einmal durchlaufen// j wird zum Vergleich mit dem Anfangsstück verwendeti := 0j := -1next[i] := jwhile(i hat das letzte Zeichen des Pattern noch nicht erreicht){if (j ist kleiner 0 ODER Buchstaben bei i und j sind gleich){inkrementiere i und jnext[i] := j} else {j := next[j]}}}3


1.3.3 BeispielBevor der Algorithmus erklärt wird, soll hier ein ganzes Beispiel durchgespielt werden. Dieses sollhelfen, den Algorithmus besser zu verstehen.Text: „mamas marmelade macht maman“Pattern: „maman“Verschiebeinformation: m a m a n-1 0 0 1 2m a m a s _ m a r m e l a d e _ m a c h t _ m a m a nm a m a nbeim “n” tritt ein Fehler aufm a m verschieben um zwei Stellen an die Position 2 des Patternsmmm a m1.3.4 ImplementierungDie Implementierung der Methode search_kmp() ist ganz ähnlich wie die Methode initnext() diedas Pattern mit sich selber vergleicht.search_kmp(){}Erzeuge zwei Zeiger t und p, und setzte beide auf 0while(t hat das Ende des Textes noch nicht erreicht){}if((p ist kleiner 0) ODER (die Buchstaben bei t und p sind dieselben)){inkrementiere t und p}else{}verschiebe p gemäss Tabelleif( p hat den Wert der Länge des Patterns ){}System.out.println("Gefunden bei "+ t)Aufgabe 5Implementieren Sie die Methode search_kmp() in der Klasse KMP. Der Text soll wie das Pattern einAttribut der Klasse KMP sein.4

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!