String Matching 2. Definition Ein Alphabet ist eine nichtleere, endliche Menge S von Zeichen.

Ähnliche Dokumente
String - Matching. Kapitel Definition

Effiziente Algorithmen 2

Algorithmische Bioinformatik 1

2.2 Der Algorithmus von Knuth, Morris und Pratt

Informatik II, SS 2016

Informatik II, SS 2014

Der Boyer-Moore Algorithmus

Aminosäurenanalytik. Probenvorbereitung Eiweißfällung, Oxidation und Hydrolyse Karl-Heinz Jansen SYKAM CHROMATOGRAPHIE

Informatik II, SS 2016

Kapitel 1. Exakte Suche nach einem Wort. R. Stiebe: Textalgorithmen, WS 2003/04 11

Informatik II, SS 2018

Informatik II, SS 2018

Algorithmen und Datenstrukturen

Zeichenketten Benedikt Straßner. Programming Systems Group Martensstr Erlangen Germany

String matching: Überblick

Kapitel 5. Textalgorithmen. 5.1 Grundbegriffe

Algorithmische Bioinformatik 1

Proseminar String Matching

1.3 Knuth-Morris-Pratt-Algorithmus

Algorithmen und Datenstrukturen II. Suchen in Texten. Prof. Dr. Oliver Braun. Fakultät für Informatik und Mathematik Hochschule München

1.5 Boyer-Moore-Algorithmus

Algorithmen mit konstantem Platzbedarf: Die Klasse REG

Algorithmische Bioinformatik

Verfahren zu Strukturvorhersagen in vereinfachten Modellen. Tobias Voigt Sommerakademie 2002 St. Johann

Algorithmen und Datenstrukturen

Boyer Moore Algorithmus

Algorithmische Bioinformatik 1

Praktikum Algorithmische Anwendungen WS 2006/07 Ausarbeitung: Schnelle Stringsuchalgorithmen Boyer-Moore und Knuth-Morris-Pratt

Algorithmen zur exakten Suche in Texten. Algorithmen und Datenstrukturen II 1

Zeichenketten. 10. Mai 2017 Simon Bachstein Simon Bachstein Hallo Welt -Seminar - LS 2 Zeichenketten 1

Suche in Texten. Verschiedene Szenarios: Dynamische Texte. Texteditoren Symbolmanipulatoren. Statische Texte

Knuth Morris Pratt Algorithmus

Suchen in Texten. Naives Suchen Verfahren von Knuth-Morris-Pratt Verfahren von Boyer-Moore Ähnlichkeitssuchen Editierdistanz

Universität Bremen. Textsuche. Thomas Röfer. Naive Suche Verfahren von Knuth-Morris-Pratt Verfahren von Boyer-Moore Ähnlichkeitssuche Editierdistanz

30. Algorithmus der Woche Texte durchsuchen aber schnell Der Boyer-Moore-Horspool-Algorithmus

Zeichenketten. Michael Fularczyk Michael Fularczyk Zeichenketten / 41

11. Woche: Turingmaschinen und Komplexität Rekursive Aufzählbarkeit, Entscheidbarkeit Laufzeit, Klassen DTIME und P

TU München. Hauptseminar: WS 2002 / Einführung in Suffix - Bäume

Algorithmen und Datenstrukturen

Textsuche. Textsuche

Algorithmen zur exakten Suche in Texten

1.8 Shift-And-Algorithmus

9. Übung zur Einführung in die Informatik (HaF) (Abschnitt IV: Rechnerstrukturen und Betriebssysteme) Musterlösung

Algorithmen und Datenstrukturen II

Rückblick: Längste gemeinsame Zeichenkette

Grundlagen: Algorithmen und Datenstrukturen

Matchings in Graphen. Praktikum Diskrete Optimierung (Teil 5)

Zeichenketten. 29. April 2015 Benedikt Lorch. Benedikt Lorch Zeichenketten April

Greedy Algorithms - Gierige Algorithmen

Konstruktion von Suffix Bäumen

Grundlagen der theoretischen Informatik

Grundlagen Theoretischer Informatik I SoSe 2011 in Trier. Henning Fernau Universität Trier

Der Satz von Rice. Dann ist C(S) eine unentscheidbare Menge.

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

Informatik II Precomputation

Dendrogramm der Primaten

INFORMATIK FÜR BIOLOGEN

Algorithmus: // Zähler für jede Regel. // Initialisierung. // Initialisierung von rhs } // 2 N result = ; // Ergebnis-Menge int count[p];

Algorithmen und Datenstrukturen (Informatik II) SS Klausur

Approximationsalgorithmen

Randomisierte Algorithmen 2. Erste Beispiele

Die mathematische Seite

6 Schaltwerke und endliche Automaten

Wann sind Codes eindeutig entschlüsselbar?

Mathematisches Praktikum - SoSe 2014

Die Nerode-Relation und der Index einer Sprache L

Algorithmen und Datenstrukturen in der Bioinformatik Erstes Übungsblatt WS 05/06 Musterlösung

Mathematisches Praktikum - SoSe 2015

kontextfreie Grammatiken Theoretische Informatik kontextfreie Grammatiken kontextfreie Grammatiken Rainer Schrader 14. Juli 2009 Gliederung

Algorithmen II Vorlesung am

Übung zur Vorlesung Berechenbarkeit und Komplexität

Grundlagen der Theoretischen Informatik Musterlösungen zu ausgewählten Übungsaufgaben

ADS: Algorithmen und Datenstrukturen 1

5. Übungsblatt zu Algorithmen I im SoSe 2016

8.4 Suffixbäume. Anwendungen: Information Retrieval, Bioinformatik (Suche in Sequenzen) Veranschaulichung: DNA-Sequenzen

Ausgewählte unentscheidbare Sprachen

3.3 Laufzeit von Programmen

ADS: Algorithmen und Datenstrukturen 1

Konstruktion von Suffix Bäumen

Aminosäurebestimmung im Kochschinken

Algorithmen und Datenstrukturen 2

Einleitung. Kapitel 1

Kontextfreie Sprachen. Automaten und Formale Sprachen alias Theoretische Informatik. Sommersemester Kontextfreie Sprachen

Ein deterministischer endlicher Automat (DFA) kann als 5-Touple dargestellt werden:

Übersicht. 1 Einführung. 2 Suchen und Sortieren. 3 Graphalgorithmen. 4 Algorithmische Geometrie. 5 Textalgorithmen. 6 Paradigmen

Übungsblatt 6. Vorlesung Theoretische Grundlagen der Informatik im WS 18/19

Aufgabe 2: (Aminosäuren)

Berechenbarkeit und Komplexität Vorlesung 10

Turing Maschine. Thorsten Timmer. SS 2005 Proseminar Beschreibungskomplexität bei Prof. D. Wotschke. Turing Maschine SS 2005 p.

Berühmte Informatiker

Laufzeit einer DTM, Klasse DTIME

Grundbegriffe der Informatik Tutorium 3

Theoretische Grundlagen der Informatik. Vorlesung am 02. November INSTITUT FÜR THEORETISCHE INFORMATIK

2. Woche Eindeutige Entschlüsselbarleit, Sätze von Kraft und McMillan, Huffmancodierung

Fragen 1. Muss eine DTM ein Wort zu Ende gelesen haben, um es zu akzeptieren? a) Ja! b) Nein!

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Entartete Suchbäume. Beispiel: Balancieren von Suchbaum. Wintersemester 2012/13

Schleifeninvarianten. Dezimal zu Binär

Daten suchen und durchsuchen. Programmieren und Problemlösen Daten suchen und durchsuchen, weiterführende Komplexitätstheorie

Transkript:

1

2 1. Strings Definition Ein Alphabet ist eine nichtleere, endliche Menge S von Zeichen. Ein String über S ist eine endliche Folge S = S(1)S(2)...S(n) von Zeichen S(i) aus S, dessen Länge n wir mit S bezeichnen. Der leere String hat keine Zeichen, er hat die Länge 0 und wird mit e bezeichnet. Die Menge aller Strings über S wird mit S* bezeichnet. Die Verkettung zweier Strings S = S(1)...S(n) und T = T(1)...T(m) ist der String ST = S(1)...S(n)T(1)...T(m). Ist S ein String der Länge n und sind i und j Indizes mit 1 i j n, so ist S[i..j] der String S(i)S(i+1)...S(j). Wir nennen ihn einen Teilstring von S mit Startposition i und Endposition j. Einen Teilstring S[1..i] nennen wir ein räfix von S. Ist i < n, so heißt S[1..i] ein echtes räfix von S. Einen Teilstring S[j..n] nennen wir ein Suffix von S. Ist 1 < j, so heißt S[j..n] ein echtes Suffix von S. Eine Teilsequenz von String S = S(1)...S(n) ist ein String der Form S(i 1 )S(i 2 )...S(i k ), für eine (eventuell leere) Indexfolge i 1,i 2,...,i k mit 1 i 1 < i 2 <... < i k n. räfix Teilwort Suffix

3 Alphabete, die wir verwenden werden, sind: S binary = {0,1} S decimal = {0,1,2,3,4,5,6,7,8,9} S nucleotides = {A,C,G,T} S amino_acids = {ala, arg, asn, asp, cys, gln, glu, gly, his, ile, leu, lys, met, phe, pro, ser, thr, trp, tyr, val} 2. Algorithmus von Knuth-Morris-ratt ATTERN MATCHING EINGABE Ein String T der Länge n (Text) und ein String der Länge m (attern/suchmuster) AUFGABE Stelle fest, ob ein Teilstring von T ist. Wenn ja, finde eine oder alle Startpositionen von in T. Der triviale Algorithmus M simple legt an das linke Ende von T an und vergleicht die Zeichen von mit den entsprechenden Zeichen von T. Wird eine Stelle mit unterschiedlichen Zeichen gefunden (mismatch), so wird um eine osition nach rechts verschoben und der Vergleich beginnt von vorne. Sind alle Zeichen identisch (match), so wird die Startposition von in T ausgegeben und um eine osition nach rechts verschoben (um das nächste Vorkommen von in T zu suchen). In einem seudocode formuliert:

4 INUT string T, ; int i, j; FOR i := 1 to n-m+1 DO IF test(i) THEN output(i); ROCEDURE test(i); BEGIN FOR j := 1 TO m DO IF (j) T(i+j-1) THEN return(false); return(true); Der Algorithmus macht (n-m+1) m Vergleiche, seine Laufzeit ist also O(n m). Wir verwenden dabei die bekannte O-Notation: Definition Seien f: N Æ N und g: N Æ N Funktionen. Wir sagen, dass f = O(g) ist, falls es c > 0 und n 0 Œ N gibt, so dass f(n) c g(n) für alle n n 0 gilt. Effizientere Algorithmen erhalten wir, wenn wir beim Durchschieben des attern durch den Text T gewisse Informationen über mitprotokollieren, die es uns im Falle eines mismatches ermöglichen, weiter durch T hindurchzuschieben, ohne jeweils wieder am Anfang von mit dem erneuten Vergleichen beginnen zu müssen. Hierzu ist eine gewisse Vorverarbeitung von (preprocessing) erforderlich.

5 Beispiel: Der Text T ist anananasss und das attern ist ananas : Das erste Anlegen von an T liefert folgende Informationen: matches erster mismatch a n a n a n a s s s a n a n a s Der triviale Algorithmus würde nun von osition 6 auf osition 2 zurückfallen und dort erneut anlegen. Dass dies aber keinen Erfolg bringen kann, kann man ohne Ansehen des Textes T allein schon einer Analyse des Musters und dem aktuellen Textbuchstaben n entnehmen. Das längste Suffix von ananan, welches auch gleichzeitig räfix des bereits gelesenen und erfolgreich mit dem Text gematchten Anfangsstückes anana von ist, ist das Wort anan der Länge 4. Die nächste Chance, ein Vorkommen von zu finden, ist somit 6 4 = 2 ositionen weiter rechts von der ursprünglichen Suchposition von. An dieser Stelle können wir auch bereits 4 erfolgreiche matches aus dem vorherigen Vergleich übernehmen, ohne sie noch einmal explizit durchführen zu müssen. Anders ausgedrückt, wir gehen im Suchtext T an osition 7 einfach weiter, stellen uns dabei aber vor, dass wir das Suchmuster um 6 4 = 2 ositionen nach rechts verschoben haben: matches Hier geht der Vergleich weiter. a n a n a n a s s s a n a n a s a n a n a s maximal viele schon etablierte matches

6 Hätten wir statt des längsten ein kürzeres Suffix von ananan gewählt, etwa das Suffix an der Länge 2, das auch ein räfix von anana ist, und hätten wir in Gedanken um 6 2 = 4 ositionen nach rechts verschoben, so hätten wir ein Vorkommen von in T übersprungen: matches Hier geht der Vergleich weiter. a n a n a n a s s s a n a n a s a n a n a s schon etablierte matches Beim Vorwärtsschieben von (in Gedanken) kommt es also im Allgemeinen auf folgendes an: Wenn wir während des aktuellen Vergleichs von mit T bereits q < m viele matches gefunden haben, dann aber das q+1-te Zeichen von mit dem in T an der entsprechenden Stelle gelesenen Zeichen a nicht mehr übereinstimmt (mismatch), so benötigen wir die Länge p des längsten Suffixes von [1..q]a, welches gleichzeitig ein räfix von [1..q] ist: matches mismatch T Dann geht die Suche nach in T rechts von der mismatch-osition in T mit dem in Gedanken um p Felder nach rechts verschobenen Musters mit bereits p erfolgreich gematchten Zeichen weiter.

7 matches hier geht die Suche weiter T bereits etablierte matches Der Vorschub p ist dem attern und dem aktuelles Zeichen von T, an dem der erste mismatch aufgetreten ist, zu entnehmen, der restliche Text T spielt hierfür keine Rolle. Man berechnet vor dem Durchsuchen von T für jedes räfix [1..q], das ein potenziell erfolgreich mit T an der aktuellen Suchposition gematches räfix von sein könnte, und für jeden Buchstaben a, der ein potenzieller mismatch-buchstabe an der aktuellen osition in T sein könnte, auf Vorrat den oben beschriebenen Vorschub ( preprocessing von ). Dies lässt sich in Form eines endlichen Automaten angeben. Definition Ein endlicher Automat M ist ein 5-Tupel (Q,S,d,i,F) mit folgenden Bestandteilen: Q ist eine nichtleere endliche Menge (der Zustände) S ist ein Alphabet (der Eingabezeichen) d: Q S Æ Q ist die Überführungsfunktion i Œ Q ist der Initialzustand F Õ Q ist die Finalmenge

8 Ein endlicher Automat liest, beginnend im Zustand i, einen String S Zeichen für Zeichen von links nach rechts und verändert in Abhängigkeit vom gelesenen Zeichen gemäß seiner Überführungsfunktion seinen Zustand. Ist der letzte Zustand ein Element von F, so wird S akzeptiert, ansonsten wird S verworfen. Formal lässt sich dies wie folgt definieren: Definition Sei M = (Q,S,d,i,F) ein endlicher Automat. Wir definieren die Funktion d*: Q S* Æ Q als Erweiterung der Funktion d: Q S Æ Q wie folgt: d*(q,e) = q d*(q,as) = d*(d(q,a),s) Der Automat M akzeptiert den String S, falls d*(i,s) Œ F. Der Automat M verwirft den String S, falls d*(i,s) œ F. Die von M akzeptierte Sprache ist die Menge L(M) := { S M akzeptiert S }. Zu einem attern der Länge m über S betrachten wir den endlichen Automaten M := ({0,1,...,m},S,d,0,{m}) mit folgender Überführungsfunktion: d (q,a) := Länge des längsten Suffixes von [1..q]a, das gleichzeitig ein räfix von [1..q] ist

9 Für das Suchmuster ananas würde die Überführungsfunktion wie folgt aussehen Anzahl erfolgreich gematchter Zeichen a n a n a s 0 1 2 3 4 5 6 nächstes gelesenes Zeichen im Text a n s 1 0 0 1 3 1 5 1 1 2 0 4 0 4 0 0 0 0 0 6 0 sonst 0 0 0 0 0 0 0 Dass wir für jedes Alphabetzeichen eine eigene Zeile berechnen und abspeichern müssen, ist insbesondere vom Aspekt des Speicherplatzverbrauches etwas lästig. Wir werden in Kürze eine alternative, in dieser Hinsicht günstigere und auch etwas einfacher zu analysierende Vorgehensweise betrachten. Die naive Methode, den endliche Automaten M zu erzeugen, würde für alle q von 0 bis m, jedes Zeichen a und alle möglichen Suffixlängen k von 0 bis q das Suffix [q-k+1..q]a mit dem räfix [1..k] vergleichen, bis das maximale k mit [q-k+1..q]a = [1..k] gefunden ist. Das würde O(m 3 ) viele Vergleiche erforderlich machen. Glücklicherweise geht es wesentlich besser, nämlich in O(m) Schritten. 1 Haben wir den endlichen Automaten in O( ) Schritten erzeugt, so können wir mit dem folgenden Algorithmus M finiteautomaton in einem beliebigen Text T in O( T ) Schritten wie folgt nach suchen: 1 Wir werden dies nicht beweisen, sondern in Kürze ein ähnliches reprocessing im nächsten Algorithmus von Knuth, Morris und ratt behandeln. Der interessierte Leser möge das dortige Vorgehen auf die hier vorliegende Situation übertragen.

10 INUT string, T; int n, m, q, k ; erzeuge den endlichen Automaten M ; n := T ; m := ; matchanzahl := 0 ; FOR k := 1 TO n DO matchanzahl := d (matchanzahl,t(k)); IF matchanzahl = m THEN output(k m + 1) ; Die Gesamtlaufzeit in O( + T ), also linear in der Eingabelänge. Ein leicht modifiziertes Vorgehen führt zum Algorithmus von Knuth-Morris-ratt. Der Unterschied zum vorigen Algorithmus ist, dass wir allein aus dem attern heraus eine Verschiebetabelle berechnen, die uns sagt, wie weit nach rechts zu verschieben ist, wenn ein Mismatch zwischen und T auftritt. Bei dieser Verschiebung berücksichtigen wir dabei nicht den mismatch-buchstaben a von T. Dies hat den Vorteil, dass wir nicht für alle S vielen Zeichen a (wie oben) Verschiebungen ausrechnen müssen, von denen viele vielleicht im Verlauf des Durchgangs durch den Text T gar nicht auftauchen. Der Nachteil ist, dass wir eventuell etwas zu zaghaft verschieben (zu ositionen, an denen gar nicht auftreten kann, wenn man die Information aus dem Mismatch berücksichtigen würde) und dies deshalb weitere Male durchführen müssen, bis ein nächster Match eintritt. Die Details: Für q =1,..., m sei p (q) die Länge des längsten echten Suffixes von [1..q], das auch räfix von [1..q] ist. Wir müssen dabei echte Suffixe betrachten, weil ansonsten stets p (q) gleich q wäre, also nie weiter geschoben werden würde. Zur Illustration ein Ablauf mit zweimaligem Vorschub:

11 mismatch an osition q + 1 T matches Vorschub zur nächsten Matchoption: erneuter mismatch an osition q + 1 T matches Erneuter Vorschub zur nächsten Matchoption: match an osition q + 1 T

12 Entweder kommt es an der aktuellen osition q + 1 nach endlich vielen Vorschüben zu einem Match, oder es ist irgendwann einmal das gesamte Muster über die osition q hinweg geschoben worden (erkennbar an p (q) = 0). q p (q) a n a n a s 1 2 3 4 5 6 0 0 1 2 3 0 Beispiel einer Tabelle mit den Vorschüben an allen potenziellen mismatch-ositionen Der Algorithmus M Knuth-Morris-ratt arbeitet nun wie folgt: INUT strings und T; int m := ; int n := T ; int matchanzahl := 0 ; int k ; Berechne die Verschiebetabelle von ; FOR k := 1 TO n DO WHILE (matchanzahl > 0 AND (matchanzahl + 1) T(k)) DO matchanzahl := p (matchanzahl); IF (matchanzahl + 1) = T(k) THEN matchanzahl := matchanzahl + 1; IF matchanzahl = m THEN output(k m + 1); matchanzahl := p (matchanzahl);

13 Nach Berechnung der Verschiebetabelle von, die wir gleich noch durchführen müssen, wird der Text von links nach rechts einmal durchlaufen; die osition, an der jeweils (in Gedanken) angelegt wird, läuft hinterher. Insgesamt kann höchstens n mal nach rechts verschoben werden, so dass der Gesamtaufwand O(2n) = O(n) ist. Eine alternative Begründung, die aber dasselbe beinhaltet und zum selben Ergebnis führt, erhält man, wenn man den Verlauf der Werte von matchanzahl und k protokolliert und folgendes beachtet: Wenn sich k verändert, dann nur zu k+1; matchanzahl kann bei stagnierendem k mehrmals kleiner werden (auch um mehr als 1), aber höchstens so oft, wie k vorher größer geworden war. Ein typischer Verlauf sieht also wie folgt aus: matchanzahl k Die Berechnung der Verschiebetabelle muss effizient erfolgen; der triviale Algorithmus würde offensichtlich O(m 3 ) Schritte machen. Die Idee ist dieselbe wie im obigen Algorithmus, nur wird nun über sich selbst hinweg geschoben. Bei der Berechnung von p (q) für q > 1 ist das längste echte Suffix von [1..q] zu finden, das auch räfix von [1..q] ist. q

14 Lassen wir das letzte Zeichen (q) in diesem längsten Suffix weg, so erhalten wir ein echtes Suffix (nicht unbedingt das längste solche) von [1..q-1], welches auch ein räfix von [1..q- 1] ist. q Das längste echtes Suffix von [1..q-1], welches auch ein räfix von [1..q-1] ist, kennen wir aus dem vorigen Schritt des Algorithmus: q Seine Länge ist in einer Variablen matchanzahl gespeichert worden. Wir stellen uns diese Situation wiederum als einen Vorschub von über sich selbst vor: q-1 matchanzahl

15 Wir beginnen also mit diesem Vorschub und testen, ob auch noch ein Match an der Stelle q vorliegt. Nach endlich vielen Mismatches an der Stelle q und jeweils weiteren Vorschüben, die wir unter Verwendung der bereits berechneten Werte p (1,),..., p (q-1) bestimmen können, gelangen wir entweder einmal zu einem match an der Stelle q, oder das Vorschieben endet mit matchanzahl = 0. In ersterem Fall wird matchanzahl um 1 vergrößert. Am Ende enthält die Variable matchanzahl wiederum den korrekten Wert, nämlich p (q). INUT string ; int matchanzahl := 0; int m := ; int q; p (1) := 0; FOR q := 2 TO m DO WHILE ( matchanzahl > 0 AND (matchanzahl + 1) (q)) DO matchanzahl := p (matchanzahl); IF (matchanzahl + 1) = (q) THEN matchanzahl := matchanzahl + 1; p (q) := matchanzahl; Zur Illustration die Berechnung von p (q) mit zweimaligem Vorschub, der sich jeweils unter Zuhilfenahme bereits berechneter Werte p (q ) mit q < q ergibt, bei Vorliegen eines mismatches an osition q:

16 mismatch an osition q matchanzahl erneuter mismatch an osition q matchanzahl nun match an osition q matchanzahl Die osition q wandert in m Schritten von links nach rechts, wird maximal m mal hinterher geschoben. Der Aufwand für die Berechnung der Verschiebetabelle ist somit O(2m) = O(m).