Archivks
Vortrag: String-Matching
„Stringmatching / Patternmatching – Vortrag von Lars Heppert“. Folien vom 14. und 15. Februar 2004, auf der alten Seite unter „Downloads zum Vortrag in der KS“.
- Quelle der Folien: „String-Matching – Definition, Anwendung, effiziente Algorithmen“ von Dr. rer. nat. Thomas Grauschopf
Gliederung
Teil I
- Definitionen
- Anwendungen von String-Matching
- Beschreibung von DirectSearch
- Implementierung von DirectSearch
- Analyse von DirectSearch
Teil II
- Bessere Verfahren
- Beschreibung des Sunday-Algorithmus
- Implementierung von Quick-Search
- Analyse von Quick-Search
- Weitere Optimierungsmöglichkeiten
1.1 Definitionen
- Gegeben sei eine Zeichenfolge s (eng. String) der Länge N und das Muster p (eng. Pattern) der Länge M
- Ein Vergleichsfenster w (eng. Window) ist eine Teilzeichenfolge der Länge M von s
- Gesucht wird die erste Position i für 0 <= i <= N – M in s, für die das Vergleichsfenster mit dem Muster übereinstimmt: w = p
1.2 Anwendungen
- Texteditoren: Suche von Schlüsselwörtern in Text, Variablennamen in Programmen usw.
- Commandlinetools für die Textsuche z.B. grep unter Unix
- Virenscanner: Auffinden von Virensignaturen in Dateien
- Biochemie: Suche nach Basensequenzen in einem Genom
1.3 DirectSearch-Beschreibung
Vergleich zwischen Muster und String, bei welchem das Muster jeweils um 1 Zeichen nach rechts verschoben wird sobald ein Mismatch aufgetreten ist, tritt kein Mismatch auf ist der String gefunden.
Beispiel:
Pattern = „hard“
String = „Change is hard, but stagnation is fatal!“
01.Schritt hard
02.Schritt hard
...
11.Schritt hard → gefunden
1.4 DirectSearch-Implementierung
public void directSearch(byte[] s, byte[] p)
{
sloop: for(int i = 0 ; i < s.length - p.length + 1 ; i++)
{
for(int j = 0 ; j < p.length ; j++)
if(s[i+j] != p[j]) continue sloop; //Mismatch?
return i; //Pattern gefunden
}
return -1; //Pattern nicht gefunden
}Anmerkung 2026: Auf der Folie steht als Rückgabetyp void, die Methode liefert aber einen int-Wert zurück.
1.5 Analyse von DirectSearch
- Der Algorithmus durchläuft 2 verschachtelte Schleifen.
- Die Komplexität des Verfahrens liegt demzufolge bei O(N*M) → falls das Muster an jeder Position vollständig verglichen werden muss. (ungünstigster Fall)
- N und M stehen dabei für die maximale Lauflänge der beiden Schleifen.
- Die durchschnittliche Komplexität liegt allerdings nur bei O(N), weil in den meisten Fällen schon sehr früh ein Mismatch zustande kommt (im Schnitt nach dem 1,15-ten Zeichen in deutschsprachigen Texten)
2.1 Bessere Verfahren
- Knuth-Morris-Pratt Algorithmus
- Boyer-Moore Algorithmus
→ beide Verfahren verwenden Informationen aus bereits erfolgten Vergleichen.
→ die Algorithmen sind kurz aber komplex - Ähnlich effizient ist der nach seinem Entdecker D.M. Sunday benannte Algorithmus in der Quick-Search-Variante.
2.2 Der Sunday-Algorithmus
(Mismatch) (Zeichen rechts vom Vergleichsfenster)
Bsp: Pattern = „Wissen“
String = „Phantasie ist wichtiger als Wissen“
1.Schritt Wissen
String = „Phantasie ist wichtiger als Wissen“
2.Schritt Wissen
String = „Phantasie ist wichtiger als Wissen“
3.Schritt Wissen
Anmerkung 2026: Die Originalfolien mit der ursprünglichen Anordnung stehen oben als PowerPoint-Dateien zum Download.
2.3 QuickSearch-Implementierung
public static int quickSearch(byte[] s, byte[] p)
{
int[] shiftTab = new int[256]; //Shift-Tabelle
for (int i = 0 ; i < 256 ; i++)
shiftTab[i] = p.length + 1;
//Initialisierung mit Musterlänge + 1
for (int i = 0 ; i < p.length ; i++)
{
int tabPos = p[i] & 0xff; //typeCast byte→int
shiftTab[tabPos] = p.length - i;
}
int i = 0;
int pdecr = p.length - 1;
while(i < s.length - p.length + 1)
{
ploop: for (int j = 0 ; j < p.length ; j++)
{
if(s[i+j] != p[j])
break ploop;
if(j == pdecr)
return i;
}
int shiftEntry=s[i + p.length] & 0xff;
i += shiftTab[shiftEntry];
}
return -1;
}2.4 Analyse von Quick-Search
- Im ungünstigsten Fall hat er ebenfalls eine Komplexität O(N*M)
- Mit Modifikationen ähnlich zum Knuth-Morris-Pratt-Algorithmus kann der Aufwand auf O(N) beschränkt werden.
- Im günstigsten Fall werden nur O(N/M) vergleiche benötigt → wenn das Zeichen nach dem Fenster nie im String vorkommt.
2.5 Weitere Optimierungsmöglichkeiten
- Optimal-Mismatch-Strategie, d.h. man vergleicht erst die Zeichen des Musters mit dem Fenster, welche die geringste Häufigkeit haben.
- Falls die Häufigkeitsverteilung am Anfang unbekannt ist, so kann Sie dynamisch während der Suche ermittelt werden.