Exaktes Set-Matching mit Su x- oder Keyword

Werbung
Exaktes Set-Matching mit Sux- oder
Keyword-Trees
Thomas Laner (0125355)
Bernhard Pugfelder (0027467)
Christopher Thurnher (0125913)
10. Januar 2006
In dieser Ausarbeitung werden zwei grundlegende Verfahren zum Finden aller identischen Muster (Patterns) bzw. einer Menge von Mustern (exaktes Set-Matching Problem)
innerhalb eines Textes vorgestellt. Das Set-Matching Problem kommt in vielen heutigen
Anwendungen zum Tragen, wobei sicherlich die nächstliegende die Suche nach Wörtern
oder Wortteilen in Bereich der Textverarbeitung ist. Aber auch die Datenkomprimierung
(insb. Lempel-Ziv-Welch), DNS-Sequenzanalyse, Datenbankmanagement oder allgemeine Keyword-Suchprobleme sind beispielhafte Anwendungsgebiete von Set-Matching Algorithmen, wobei die Ezienz eines solchen Matching meist sehr entscheidend ist. Bei
den beiden vorzustellenden Verfahren handelt es sich einerseits um die Anwendung von
Sux-Trees oder andererseits von Keyword-Trees, welche jedoch aufgrund ihrer unterschiedlichen Konzeptionen in unterschiedlichen Anwendungskontexten zu betrachten
sind. Insbesondere die Aufwandsanalysen des Pre-Processing (Konstruktion der Datenstruktur, welche für die Suchoperationen obligatorisch sind), der Suchoperation nach
entsprechenden Mustern und der Speicheraufwand der beiden Verfahren werden in dieser Ausarbeitung vorgestellt. Hierzu ist die Ausarbeitung in zwei Abschnitte unterteilt
und ist wie folgt organisiert. Der erste Abschnitt stellt die Lösung das Set-Matching Probelm mittels Sux-Trees vor und beinhaltet weiters die Ezienzanalysen der benötigten
Tree-Konstruktion, der Suchoperation und des Speicheraufwandes. Der zweite Abschnitt
behandelt äquivalent zum ersten Abschnitt die Lösung mittels Keyword-Trees. Aufbau
des Keyword-Trees und die Suche von Mustern bzw. zugehörige Ezienzanalysen sind
wiederum Teil dieses Abschnittes.
1 Set-Matching mit Sux-Trees
1.1 Skizzierung der Idee
Die grundlegende Idee hinter dem Set-Matching Problem ist das Aunden einer Menge von Patterns
P = {P1 , . . . , Pk } in einem gewählten String S , welcher aus einzelnen Strings mit Anzahl k besteht.
Hierzu soll auch die Häugkeit des Vorkommens von P in S ermittelt werden. Ein Pattern selbst
kann ebenfalls aus einem bestimmten Zeichen oder einer beliebigen, zusammengesetzten Zeichenfolge
bestehen und zwei Pattern P1 und P2 sind genau dann identisch, wenn beide gleich lang sind und
weiters gilt: P1 [i] = P2 [i], ∀i ∈ [1, length[P1 , P2 ]. Sowohl T als auch alle möglichen Pattern P
werden über ein Alphabet Σ (Zeichensatz) deniert, wobei |Σ| im Weiteren noch ein entscheidende
Eigenschaft für das Laufzeitverhalten eines solchen Set-Matching mittels Sux-Trees ist.
1
Um die Realisierung von Set-Matching ezient zu gestalten, kann das ähnliche Prinzip wie bei
sonstigen, bekannten Suchproblemen angewendet werden, nämlich der Aufbau einer gesonderten
Datenstruktur als Baum [Wei73, Kos89]. Diese Baumstruktur wird grundsätzlich Sux-Trie genannt
und repräsentiert alle vorkommenden Suxe (Wortendungen) von S , so dass alle gültigen Patterns
Pi genau in einem bestimmten Sux Sk exakt oder als Substring enthalten ist. Die Anzahl an
Suxen für bestimmten String S entspricht genau length(S), d. h. S1 entspricht genau S , für alle
weiteren Suxe Si wird entsprechend immer das erste Zeichen entfernt. Slength(S) enthält also genau
das letzte Zeichen von S . Das folgende Beispiel mit S = bananas zeigt die Bildung von Suxen:
S1
S2
S3
S4
S5
S6
S7
= bananas
= ananas
= nanas
= anas
Sortiert =⇒
= nas
= as
=s
S2
S4
S6
S1
S3
S5
S7
= ananas
= anas
= as
= bananas
= nanas
= nas
=s
Die erhaltenen Suxe werden nun derart in einen Sux-Trie eingetragen, so dass ein bestimmter
Pfad einen Sux repräsentiert und jede Kante ein entsprechendes Zeichen darstellt. Die Sortierung
der Suxe ist für einen korrekten Aufbau des Sux-Tries notwendig und bedingt die Reihenfolge
der Kinderknoten. Die Abbildung 1 illustriert den Sux-Trie zum obigen Beispiel mit S = bananas.
Durch den Aufbau einer Baumstruktur erhält man das optimale Laufzeitverhalten für das Suchen
eines beliebigen P mit O(length(P )) (siehe auch 1.3), jedoch muss nun noch der Aufwand für
das Pre-Processing (also der Aufwand für die Konstruktion eines solchen Sux-Tries) beachtet
werden, welche mit O(count(suf f ixes)2 ) begrenzt ist. Erhöht sich jedoch die Länge von T, und
somit auch die Anzahl an Suxen, wird ein linearer Aufwand für das Pre-Processing unbedingt
notwendig, so dass anstatt eines Sux-Trie ein modizierter Sux-Tree verwendet wird. Dieser
wird durch das Zusammenfassen von Kantenfolgen ohne Verzweigen des Sux-Tries gebildet und
kann in O(count(suf f ixes)) erstellt werden. Das Pre-Processing von Sux-Trees ist jedoch stark
abhängig von |Σ|, so dass nur unter der Berücksichtigung gewisser Eigenschaften des Sux-Tree der
Aufwand mit O(count(suf f ixes)) begrenzt ist (insbesondere bei nicht konstanten Σ). Näheres zu
Pre-Processing ist in Unterabschnitt 1.2 zu nden.
Abbildung 1:
Sux-Trie zu String S = bananas
2
Die Abbildung 2 skizziert den aus Abbildung 1 resultierenden, expliziten Sux-Tree für S =
bananas (mit Ende-Zeichen s). Ein impliziter Sux-Tree beinhaltet kein zusätzliches Ende-Zeichen
für die einzelnen Suxe. Dies kann zu dem so genannten Präx-Problem führen, d. h. ein bestimmtes
Si endet nicht in einem Knoten, sondern ist Teil eines anderen Suxes Sj ⇒ Si ist Präx von Sj .
Mit dem Hinzufügen eines spezischen Ende-Zeichen am Ende jedes Si (expliziter Sux-Tree) kann
dieses Präx-Problem vermieden werden.
Abbildung 2:
Expliziter Sux-Tree zu String S = bananas
Um die Speicherung der einzelnen Suxe minimal zu halten, kann weiters anstatt der expliziten Zeichenfolge, welche Si repräsentiert, eine Indexierung mit Anfangs- und Endindex des ersten
und letzten Zeichens von Si innerhalb von T für jede Kante gespeichert werden. Somit sollte der
benötigte Speicherplatz mit O(length(suf f ixes) ∗ |Σ|) begrenzt werden können. Näheres dazu in
Unterabschnitt 1.4. Die Abbildung 3 illustriert einen solchen expliziten Sux-Tree anhand des Beispiels S = bananas.
Abbildung 3:
Expliziter, komprimierter Sux-Tree zu String S = bananas
Folgende wichtige Eigenschaften sind wesentlich für die Verwendung von Sux-Trees bei SetMatching Problemen:
• Wenn P in S vorkommt ( ⇐⇒ P ist Substring von S ) =⇒ P ist Präx von ein (oder
mehreren) Suxen und es existiert genau ein Pfad von der Wurzel aus, welche P enthält.
• Wenn P in S k -mal vorkommt, so hat der Konten am Endes des P enthaltenen Pfades genau
k Unterbäume. Diese Eigenschaft ist jedoch nur in expliziten Sux-Trees immer gültig.
• Jeder innere Knoten v auf dem Pfad P = yE , wobei y als ein beliebiges Zeichen und E als eine
3
beliebige (auch leere) Zeichenfolge deniert sind, existiert immer ein weiterer innerer Knoten
v 0 mit dem Pfad P 0 = E . Die Beziehung von v und v 0 wird als Sux-Link bezeichnet.
1.2 Konstruktion des Sux-Trees
Das wesentliche Kriterium der Verwendung von Sux-Trees ist ein möglichst ezienter Aufbau des
zu S gehörenden Trees, welcher alle denierten Suxe Si , i ∈ [1, length(T )] enthält. Zusätzlich soll
jeder aufgebaute Sux-Tree T auch explizit sein, so dass tatsächlich alle Eigenschaften E1-3 gültig
sind. Dabei kann ein einfacher, naiver Algorithmus schnell gefunden werden, nämlich das sukzessive
Einfügen aller Suxe in den Sux-Tree T . Hierbei wird T mit einer Kante für den Sux S1 (also
gesamten String S ) und einem angefügten Ende-Zeichen initialisiert. Danach wird nacheinander
die Suxe S2 ...Sm derart eingefügt, dass der längst bisher in T zutreende Pfad gesucht und eine
entsprechend notwendige Pfaderweiterung durchgeführt wird.
Hierzu kann es notwendig werden, eine bestehende Kante durch einen Knoten aufzuspalten oder
einen neuen Knoten an einen bestehenden Elternknoten hinzuzufügen. Dieser naive Algorithmus
zeigt aber bei wachsender Anzahl an Suxen in S aufgrund der notwendigen i-Vergleiche für Sux
Si ein Laufzeitverhalten von O(m2 ). Um das Laufzeitverhalten auf O(m) zu drücken, müssen die
in Unterabschnitt 1.1 denierten Eigenschaften E1-3 genützt werden. Weiters muss noch die Gröÿe
das zugrunde liegende Alphabet |Σ| beachtet werden, insbesondere bei einem nicht konstanten |Σ|
kann ein Aufbau von O(m) nur unter spezischen Annahmen garantiert werden.
Im Falle eines konstanten Alphabets |Σ| = σ ist ein linearer Aufwand unabhängig der Art von
Σ garantiert, wobei insbesondere die Algorithmen [Wei73, McC76, Ukk83, Ukk95] eine Lösung
präsentieren. Weiters wird in [GK97] die bekanntesten Algorithmen zum Aufbau von Sux-Trees
bei Σ = const gegenübergestellt und evaluiert. Ist |Σ| nicht konstant, so kann beispielsweise für ein
Σ = N mittels des Algorithmus [Far97] ein Aufbau mit linearer Aufwand realisiert werden.
Der Algorithmus aus [Ukk95] basiert auf dem folgenden einfachen Schema, welches die Zeichen
2 . . . m aus S sukzessive in T einfügt, so dass nach dem i-ten Zeichen die Suxe S1...i in Ti enthalten
wird. Zusätzlich wird in einem nachfolgenden Schritt noch für alle Suxe S2...m ein Ende-Zeichen
eingefügt. Initialisiert wird T1 mit dem Sux Sm mit angefügten Ende-Zeichen Das Hauptkriterium
für die Ezienz dieses Aufbau-Algorithmus ist die notwendige Pfaderweiterung für jedes Zeichen i
bei der Betrachtung aller bereits eingefügten Teil-Suxe. Hierzu muss sowohl die eigentliche Erweiterung als auch die Suche in bestehenden Pfaden betrachtet werden.
• Im Kontext der Pfaderweiterung für jeden Schritt i müssen folgende drei Erweiterungsfälle
unterschieden werden:
1. Wenn der Pfad E = S[j . . . i − 1] in einem Blatt endet =⇒ Füge Zeichen S[i] am Ende
der letzten Kanteninfo ein.
2. Wenn der Pfad E = S[j . . . i − 1] im Inneren von Ti−1 endet und keine Fortsetzung mit
S[i] existiert =⇒ neue Kante und Blatt bzw. falls notwendig auch neuen inneren Knoten
einfügen.
3. Wenn E = S[j . . . i − 1] + S[i] bereits in Ti−1 enthalten ist =⇒ keine Erweiterung notwendig.
• Für jede Pfaderweiterung muss der Teilpfad E = S[j . . . i − 1] nicht immer von der Wurzel aus
gesucht werden, sondern mit Hilfe der Eigenschaft E3 (Sux-Links) kann die Suche bereits
nahe bei den Blättern begonnen werden. D. h. der Aufwand für die Suche von Teilpfaden wird
dadurch wesentlich verringert.
Der Übergang von Ti−1 → Ti kann immer konstant durchgeführt werden, die Anzahl an Pfaderweiterungen kann durch zusätzlichen Bedingungen (Einmal Blatt immer Blatt, Beendigung einer
4
Iteration bei Erweiterungsfall 3) bei der Pfaderweiterung mit O(m) beschränkt werden. Durch die
Verwendung von Sux-Links kann ebenfalls die Suche des Teilpfades E auch mit O(m) realisiert
werden, so dass insgesamt der Aufbau von T bezüglich eines Strings S mit linearen Aufwand implementiert werden kann.
Bei dem nicht konstanten Alphabet Σ = N kann die Methode von [Far97] zum Aufbau des
zugehörigen Sux-Tree T mit einem Aufwand von O(m) angewendet werden. Hierbei wird mittels
Divide-and-Conquer (also rekursiv) in den ersten beiden Schritten zwei Sux-Tries T0 und T1
erstellt, welche jeweils alle ungeraden bzw. geraden Suxe beinhalten. In einem dritten und letzten
Schritt werden T0 und T1 zu dem Sux-Tree T verschmolzen. Dieser Schritt ist entscheidend für die
Ezienz, es kann aber gezeigt werden, dass durch die Ausnützung von strukturellen Eigenschaften
ein O(m) erreicht werden kann.
1.3 Suchen von Mustern in Sux-Trees
Bei der Suche werden mögliche Vorkommen eines Patterns P im Sux-Tree T überprüft. Dabei
wird einfach von der Wurzel ausgehend jeweils jene Kante verfolgt dessen Kanteninfo eine passende
Fortsetzung von P in T repräsentiert. Dies wird solange wiederholt bis das Ende von P erreicht
wird oder aber keine passende Kantenfortsetzung mehr für P in T existiert. Für den Fall dass das
Pattern enthalten ist müssen also genau n Zeichenvergleiche getätigt werden, ist P nicht enthalten
wird die Schleife schon früher abgebrochen. Daraus ergibt sich ein Aufwand von O(n), wobei n die
Länge von P ist.
Noch schneller wird die Suche, wenn man davon ausgehen kann dass P garantiert im Suchstring
enthalten ist. In diesem Fall wird die Kanteninfo einfach ignoriert und nur noch die Zeichentiefe d
ist entscheidend für ein Weitergehen oder einen Abbruch, dabei gelten folgende Regeln:
d=n
d>n
d<n
Ende von P in diesem Knoten
Ende von P liegt um d-n Zeichen davor auf der Kante
Weiterverzweigen
Dadurch reduziert sich der Aufwand auf O(n0 ), wobei n0 die Anzahl der Knoten auf dem Suchweg
repräsentiert.
Bei der Suche nach allen Vorkommen muss man zusätzlich vom erreichten Ende von P zu allen, von
dort aus erreichbaren Blättern weitergehen. Die Anzahl der Vorkommen k entspricht der Anzahl
der erreichten Blätter, dazu gibt es maximal 2k Kanten und man benötigt auch nur ebenso viele
Verzweigungen. Also folgt man der Reihe nach allen Verzweigungen, daher ist der Aufwand O(n0 +k).
1.4 Speichern von Sux-Trees
Aufgrund der vielen Kanteninformationen wäre der Speicherbedarf sehr groÿ. Aus diesem Grund
bedient man sich eines einfachen Tricks: Jede Kanteninformation ist ein Substring des zu durchsuchenden Strings S. Wenn man statt des Substrings lediglich die Indizes p (von) und q (bis) speichert,
so ist der Speicherbedarf für den gesamten Sux-Tree für m Suxe O(m), wobei m die Länge des
Strings ist.
Zur Verwaltung der Nachfolger eines Knotens gibt es folgende Varianten:
Arrays Das Array hat die Gröÿe |Σ|, daher ergibt sich der Gesamtplatzbedarf für einen Sux-Tree
von O(m · |Σ|), dafür kann der Zugri aber in konstanter Zeit erfolgen (O(1)).
Lineare Liste (sortiert oder unsortiert) Der Platzbedarf ist proportional zur Anzahl der Nachfol-
ger also der Anzahl der Knoten, da jeder Knoten mit Ausnahme der Wurzel Nachfolger eines
Knotens ist. Durch die Proportionalität zu m, ist der Platzbedarf in O(m). Die Zugriszeit
5
allerdings ist proportional zu |Σ| bzw. zur Gröÿe des Alphabets also in O(|Σ|), was vor allem
bei groÿen Alphabeten sehr langsam ist.
Balancierte Bäume Platzbedarf gleich wie bei linearen Listen, aber die Zugriszeit etwas schneller,
nämlich in O(log |Σ|).
Hashtabellen Hashtabelle der Gröÿe O(m). Zugri in konstanter Zeit (O(1)), aber nur unter der
Annahme das die Berechnung der Hashfunktion in konstanter Zeit berechnen lässt.
Knoten nahe der Wurzel haben meist sehr viele Nachfolger (folglich wären Arrays besonders gut
geeignet), während weiter entfernte Knoten dagegen meist weniger Nachfolger haben (aus Speicherplatzgründen eine der anderen Varianten besser geeignet). Aus diesem Grund wäre daher eine
Mischung der genannten Datenstrukturen ideal.
1.5 Zusammenfassung
Die folgende Tabelle faÿt nochmals den Aufwand für die Operationen Konstruktion und Suchen im
Falle von String-Matching und in Abhängigkeit zu Σ dar.
S ...zu Grunde liegender String
T ...zugehöriger Sux-Tree
P ...Menge von Mustern
Pi ...einzelnes Muster aus P
ki ...Vorkommnisse von Pi
Tabelle 1:
Operation
Aufwand
Aufbau von T
O(length(S))
Suchen von Pi
O(length(Pi ))
Aufwand bei Verwendung von Arrays zur Darstellung von T .
Im Kontext von Set-Matching wird der Aufwand entsprechend der Menge P angepaÿt:
Gesamtaufwand bei Set-Matching
O(length(S) +
P
length(Pi ) +
P
ki )
2 Set-Matching mit Keyword-Trees
2.1 Skizzierung der Idee
Der Aho-Corasick-Algorithmus [AC75] wurde 1975 von Alfred V. Aho und Margaret J. Corasick
entwickelt. Anders als beim Sux-Tree baut diese Methode ausgehend von Keywords einen endlichen Automaten auf und vergleicht diesen dann mit dem Eingabetext. Dieses Verfahren bietet sich
besonders an, wenn die Keywords nach denen gesucht wird bekannt sind und sich nicht oft andern,
da dann der Aufbau des Automaten oine geschehen und er zur späteren Verwendung abgespeichert
werden kann.
6
2.2 Konstruktion des Keyword-Trees
Bevor die Suche in einem beliebigen Text beginnen kann, muss der Keyword-Tree anhand von
bestimmten vorher bekannten Keywords aufgebaut werden. Das Verhalten des Keyword-Tree Automaten wird durch 3 Funktionen bestimmt, der goto, output und failure Funktionen. Die Zustände
bzw. Knoten des Automaten werden durchnummeriert, die Zustandsübergange werden anhand der
goto Funktion bestimmt. Sie bestimmt, mit welchem Zeichen man von einem Zustand in einen anderen wechseln kann. Von einem Knoten aus kann es nie 2 Kanten mit den gleichen Zeichen geben.
Am Anfang hat man nur einen Knoten mit Nummer 0. Ausgehend vom diesem Knoten werden
nacheinander die Buchstaben der Keywords eingefügt, die goto Funktion für jeden Zustand wird
dabei erstellt. Endet an einem Knoten ein Keyword, so wird die output Funktion für diesen Knoten
mit dem Keyword versehen. Am Ende dieser Phase schaut der Automat dann wie in Abbildung 4
aus (Keyword-Tree mit Keywords he, she, his, hers ).
Abbildung 4: Keyword-Tree mit goto (Zustandsübergänge) und output Funktionen in geschwungenen Klam-
mern
Danach muss noch für jeden Knoten die failure Funktion berechnet werden. Diese Funktion gibt
an, bei welchem Zustand im Automaten fortgesetzt werden soll, wenn beim Suchen im Text ein
Zeichen kommt, für dass es keinen geeigneten Übergang im aktuellen Zustand gibt. Diese Funktion
wird für alle Knoten mit ansteigender Tiefe berechnet. Zunächst wird für alle Knoten mit Tiefe
1 die failure Funktion auf 0 gesetzt (0 ist die Nummer des Knotens, also der Startknoten). Für
alle anderen Knoten wird dann folgendes Verfahren verwendet: Man merkt sich das Zeichen a mit
dem man von Vorgängerknoten r in den aktuellen Knoten s gekommen ist und setzt die Variable
state auf den Zustand f ailure(r). Falls im Knoten state nun ein Zustandsübergang existiert, mit
dem man mit den Zeichen a in einen anderen Zustand übergehen kann (goto(state, a) existiert), so
setzt man f ailure(s) auf goto(state, a). Danach muss man noch die output Funktion von s mit der
output Funktion von f ailure(s) verschmelzen. Falls kein solchen Übergang existiert, so setzt man
state auf f ailure(state) und versucht es erneut. Falls nie ein passender Übergang gefunden wird,
man also wieder im Startknoten angekommen ist, so setzt man f ailure(s) auf 0.
In Abbildung 5 sind zum oberen Beispiel nun auch die failure Funktionen eingezeichnet. Beispielsweise merkt man sich für den Knoten 4 merkt das Zeichen h, geht entlang der failure Funktion von
Zustand 3 (Vorgängerknoten) auf Zustand 0, dort kommt man mit goto(0, h) auf Zustand 1, also ist
die failure Funktion von Zustand 4 Zustand 1. Analog dazu ist die failure Funktion von Zustand 5
Zustand 2. Da in Zustand 2 jedoch der Wert der output Funktion he ist, muss man noch die output
Funktion von Zustand 5 (she ) mit der von Zustand 2 verschmelzen.
Die Konstruktion gliedert sich also in 2 Teile. der erste Teil ist der Aufbau des Automaten anhand
der Keywords. Der Aufwand dafür ist O(n) (n ist die Anzahl der Kanten). Für die Fehlerlinks gilt:
Es kann nie mehr Rückschritte geben als die aktuelle Tiefe des Knotens. Da die failure Funktionen
7
Abbildung 5:
Keyword-Tree mit failue Funktion (gestrichelte Pfeile)
der vorangegangenen Knoten schon existieren, man also nicht alle vorhergehenden Knoten noch mal
abarbeiten muss, kann es höchstens so viele Rückwärtsschritte wie Knoten, also maximal n geben.
Daher ist die Laufzeit für die Konstruktion der failue Funktion O(n).
2.3 Suchen von Mustern in Keyword-Trees
Hat man einmal den Automaten erstellt, kann man ganz einfach die verarbeiteten Keywords in
einem beliebigen Text in linearem Zeitaufwand nden. Der Text wird als Eingabe String übergeben.
Für jedes Zeichen im Text geht man im Automaten anhand der goto Funktion in den nächsten
Zustand über. Falls die output Funktion dieses Knotens einen Wert hat, bzw. ein Keyword darin
endet, so wird es ausgegeben. Falls im aktuellen Zustand kein kein Übergang mit dem aktuellen
Zeichen existiert, dann liefert die goto Funktion fail. In diesem Fall geht man die failure Funktion
des aktuellen Zustands entlang, solange bis die goto Funktion des neuen Zustands mit dem aktuellen
Zeichen nicht fail liefert, oder man wieder im Startknoten ist.
Der Suchaufwand beim Keyword-Tree liegt im O(m) (m ist die Länge des Textes). Jedes Zeichen
wird einzeln abgearbeitet, für jedes Zeichen führen wir einen goto und möglicherweise mehrere failure
Schritte aus. Nach einem goto Schritt bleibt man entweder im Startknoten oder man geht in einen
anderen Knoten dessen Tiefe um 1 gröÿer ist als der vorherige; die maximale Tiefe ist m. Da jeder
failure Schritt in einen Knoten mit geringerer Tiefe endet, kann man pro Zeichen maximal m failure
Schritte benötigen. Da man aber erst einmal erfolgreiche (goto) Schritte braucht um in eine höhere
Tiefe zu gelangen, kann man höchstens so viele failure Schritte benötigen wie goto Schritte. Daher
ist der Suchaufwand mit 2m begrenzt, was einen Aufwand von O(m) entspricht.
8
2.4 Zusammenfassung
Hier nur Auistung der Ezienzdaten zu den oben erwähnten Operationen.
n ...Anzahl der Knoten
m...Anzahl der Zeichen im Text
Tabelle 2:
Keyword-Tree
Aufwand
Konstruktion
O(n)
Suche
O(m)
Aufwand der Verwendung des Keyword-Trees bei Set-Matching Problemen.
Literatur
[AC75]
[Far97]
A. V. Aho and M. J. Corasick. Ecient string matching: An aid to bibliographic search.
Communications of the ACM, 18(6):333340, 1975.
M. Farach. Optimal sux tree construction with large alphabets. In Proceedings of
, pages 137143,
Miami Beach, Florida, 1997.
the 38th IEEE Annual Symposium on Foundations of Computer Science
[GK97]
Robert Giegerich and Stefan Kurtz. From Ukkonen to McCreight and Weiner: A unifying
view of linear-time sux tree construction. Algorithmica, 19(3):331353, 1997.
[Heu05] V. Heun. Kapitel 2: Algorithmische Bioinformatik. http://wwwmayr.informatik.
tu-muenchen.de/lehre/2002SS/cb/lecturenotes/chapter2.pdf, Mai 2005.
Slides of the Lecture
[Kil05]
Algorithmische Bioinformatik
in PDF-Format.
Pekka Kilpeläinen. Lecture 4: Set matching and Aho-Corasick Algorithm. http://www.
cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf, Spring 2005.
Slides of the Lecture
Biosequence Algorithms
in PDF-Format.
[Kos89] S. Rao Kosaraju. Ecient tree pattern matching. In Proceedings of the
posium on the Foundations of Computer Science, pages 178183, 1989.
30th IEEE Sym-
[McC76] Edward M. McCreight. A space-economical sux tree construction algorithm.
23(2):262272, 1976.
J. ACM
,
[Ukk83] Esko Ukkonen. On approximate string matching. In Proceedings of the 1983 International
FCT-Conference on Fundamentals of Computation Theory, pages 487495, London, UK,
1983. Springer-Verlag.
[Ukk95] Esko Ukkonen. On-line construction of sux trees.
, 14(3):249260, 1995.
Algorithmica
[Wei73] P. Weiner. Linear pattern matching algorithms. In Proceedings of the
Symposium on Switching and Automata Theory, pages 111, 1973.
9
14th IEEE Annual
Herunterladen