Stefan Edelkamp Zeichenkettensuche (II) Institut für Informatik, Universität Freiburg 1 Suffixbäume Ein String W besitzt genau |W | unterschiedliche Endstücke, bestehend aus insgesamt 1 Suffixbäume Ein String W genau |W | unterschiedliche Endstücke, bestehend aus besitzt | insgesamt |W ∈ Ω(|W |2) unterschiedlichen Zeichen. 2 1 Suffixbäume Ein String W genau |W | unterschiedliche Endstücke, bestehend aus besitzt | insgesamt |W ∈ Ω(|W |2) unterschiedlichen Zeichen. 2 Ergänzt man alle Worte W um ein spezielles Endsymbol $, und fügt man die Suffixe von dem erweiterten Wort W in eine Mehrwegsuchbaumstruktur ein, so erhält man einen Suffixtrie (siehe Abbildung 1). 1 Suffixbäume Ein String W genau |W | unterschiedliche Endstücke, bestehend aus besitzt | insgesamt |W ∈ Ω(|W |2) unterschiedlichen Zeichen. 2 Ergänzt man alle Worte W um ein spezielles Endsymbol $, und fügt man die Suffixe von dem erweiterten Wort W in eine Mehrwegsuchbaumstruktur ein, so erhält man einen Suffixtrie (siehe Abbildung 1). Stefan Edelkamp Suffixbäume 1 0 1 $ 1 0 $ $ 0 $ 1 0 1 0 1 $ 0 $ Abbildung 1 Satz 1 (Suffixtrie) Jeder Knoten im Suffixtrie für W entspricht genau einem der unterschiedlichen Teilstrings von W . 0 1 $ 1 0 $ 0 $ 1 0 1 $ 0 1 $ 0 $ Abbildung 1 Satz 1 (Suffixtrie) Jeder Knoten im Suffixtrie für W entspricht genau einem der unterschiedlichen Teilstrings von W . Stefan Edelkamp Suffixbäume 2 Beweis: Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Beweis: Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Unterschiedliche Zeichenketten führen in einem Mehrwegsuchbaum aber auch zu unterschiedlichen Knoten. Beweis: Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Unterschiedliche Zeichenketten führen in einem Mehrwegsuchbaum aber auch zu unterschiedlichen Knoten. Leider gibt es für den Suffixtrie für W noch immer Beispiele mit Ω(|W |2) vielen Knoten. Beweis: Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Unterschiedliche Zeichenketten führen in einem Mehrwegsuchbaum aber auch zu unterschiedlichen Knoten. Leider gibt es für den Suffixtrie für W noch immer Beispiele mit Ω(|W |2) vielen Knoten. Beispiel 1 Zeichenketten der Form 1k 0k $ haben die Länge 2k + 1 und k2 + 4k + 2 voneinander unterschiedliche Teilstrings. Beweis: Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Unterschiedliche Zeichenketten führen in einem Mehrwegsuchbaum aber auch zu unterschiedlichen Knoten. Leider gibt es für den Suffixtrie für W noch immer Beispiele mit Ω(|W |2) vielen Knoten. Beispiel 1 Zeichenketten der Form 1k 0k $ haben die Länge 2k + 1 und k2 + 4k + 2 voneinander unterschiedliche Teilstrings. Ein Suffixbaum (vergl. Abbildung 2) ist eine kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Ein Suffixbaum (vergl. Abbildung 2) ist eine kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Die durch die Elimination von Knoten mit Grad zwei gewonnene Struktur wird im allgemeinen Patricia-Baum genannt. Ein Suffixbaum (vergl. Abbildung 2) ist eine kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Die durch die Elimination von Knoten mit Grad zwei gewonnene Struktur wird im allgemeinen Patricia-Baum genannt. Der Begriff Patricia ist von Morrison geprägt worden und ist ein Akronym aus dem die Struktur beschreibenden Satz practical algorithm to retrieve information coded in alphanumeric. Ein Suffixbaum (vergl. Abbildung 2) ist eine kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Die durch die Elimination von Knoten mit Grad zwei gewonnene Struktur wird im allgemeinen Patricia-Baum genannt. Der Begriff Patricia ist von Morrison geprägt worden und ist ein Akronym aus dem die Struktur beschreibenden Satz practical algorithm to retrieve information coded in alphanumeric. Weiner war der erste, der den Suffixbaum genauer studierte und somit einen expliziten Index für alle unterschiedlichen Teilstrings eines gegebenen Strings angab. Ein Suffixbaum (vergl. Abbildung 2) ist eine kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Die durch die Elimination von Knoten mit Grad zwei gewonnene Struktur wird im allgemeinen Patricia-Baum genannt. Der Begriff Patricia ist von Morrison geprägt worden und ist ein Akronym aus dem die Struktur beschreibenden Satz practical algorithm to retrieve information coded in alphanumeric. Weiner war der erste, der den Suffixbaum genauer studierte und somit einen expliziten Index für alle unterschiedlichen Teilstrings eines gegebenen Strings angab. Stefan Edelkamp Suffixbäume 3 0 1 $ α aα (3,3) (6,6) 10$ $ Abbildung 2 (4,6) 0 (6,6) (1,1) $ Suffixlink (6,6) 1010$ (3,3) 10$ (4,6) (2,6) 0 1 $ α aα (3,3) (6,6) 10$ $ Abbildung 2 (4,6) 0 (6,6) (1,1) $ Suffixlink (6,6) 1010$ (3,3) 10$ (4,6) (2,6) Jeder Knoten im Suffixbaum für W hat mehr als einen Nachfolger und W viele Blätter. 0 1 $ α aα (3,3) (6,6) 10$ $ Abbildung 2 (4,6) 0 (6,6) (1,1) $ Suffixlink (6,6) 1010$ (3,3) 10$ (4,6) (2,6) Jeder Knoten im Suffixbaum für W hat mehr als einen Nachfolger und W viele Blätter. Die Kantenbeschriftungen werden als Intervall des zugrundeliegenden Strings an den Knoten verwaltet, auf dem die Kante einläuft, so dass der Suffixbaum nur O(|W |) Platz benötigt. 0 1 $ α aα (3,3) (6,6) 10$ $ Abbildung 2 (4,6) 0 (6,6) (1,1) $ Suffixlink (6,6) 1010$ (3,3) 10$ (4,6) (2,6) Jeder Knoten im Suffixbaum für W hat mehr als einen Nachfolger und W viele Blätter. Die Kantenbeschriftungen werden als Intervall des zugrundeliegenden Strings an den Knoten verwaltet, auf dem die Kante einläuft, so dass der Suffixbaum nur O(|W |) Platz benötigt. Stefan Edelkamp Suffixbäume 4 Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Der Ort einer Zeichenkette α ist der Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls er existiert). Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Der Ort einer Zeichenkette α ist der Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls er existiert). Eine Erweiterung einer Zeichenkette α ist jede Zeichenkette, die α als Präfix hat. Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Der Ort einer Zeichenkette α ist der Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls er existiert). Eine Erweiterung einer Zeichenkette α ist jede Zeichenkette, die α als Präfix hat. Der erweiterter Ort einer Zeichenkette α ist der Ort der kürzesten Erweiterung von α, deren Ort definiert ist. Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Der Ort einer Zeichenkette α ist der Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls er existiert). Eine Erweiterung einer Zeichenkette α ist jede Zeichenkette, die α als Präfix hat. Der erweiterter Ort einer Zeichenkette α ist der Ort der kürzesten Erweiterung von α, deren Ort definiert ist. Der kontraktierter Ort einer Zeichenkette α ist der Ort des längsten Präfixes von α, dessen Ort definiert ist. Definition 1 Ein partieller Weg ist eine zusammenhängende, bei der Wurzel beginnende Folge von Kanten. Ein Weg ist ein partieller Weg, der bei einem Blatt endet. Der Ort einer Zeichenkette α ist der Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls er existiert). Eine Erweiterung einer Zeichenkette α ist jede Zeichenkette, die α als Präfix hat. Der erweiterter Ort einer Zeichenkette α ist der Ort der kürzesten Erweiterung von α, deren Ort definiert ist. Der kontraktierter Ort einer Zeichenkette α ist der Ort des längsten Präfixes von α, dessen Ort definiert ist. Stefan Edelkamp Suffixbäume 5 Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel 2 Sei W = ababc, dann Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel 2 Sei W = ababc, dann suf = Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel 2 Sei W = ababc, dann suf = abc, head3 = Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel 2 Sei W = ababc, dann suf = abc, head3 = ab, und tail3 = Definition 2 Der Suffix sufi ist der an Position i beginnendes Suffix von W , also z.B. suf = W . Der String headi ist der längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel 2 Sei W = ababc, dann suf = abc, head3 = ab, und tail3 = c. T0 = T1 = T2 = ababc ababc babc Stefan Edelkamp Suffixbäume 6 Die definierende Eigenschaft aus Satz 1 liest sich für Suffixbäume wie folgt: Die definierende Eigenschaft aus Satz 1 liest sich für Suffixbäume wie folgt: Satz 2 (Suffixbaum) Jeder innere Knoten t im Suffixbaum für W entspricht dem größten gemeinsamen Präfix zweier Suffixe von W . Die definierende Eigenschaft aus Satz 1 liest sich für Suffixbäume wie folgt: Satz 2 (Suffixbaum) Jeder innere Knoten t im Suffixbaum für W entspricht dem größten gemeinsamen Präfix zweier Suffixe von W . Die diese Suffixe beschreibenden Blätter finden sich in zwei unterschiedlichen Zweigen des Teilbaumes zu t. Die definierende Eigenschaft aus Satz 1 liest sich für Suffixbäume wie folgt: Satz 2 (Suffixbaum) Jeder innere Knoten t im Suffixbaum für W entspricht dem größten gemeinsamen Präfix zweier Suffixe von W . Die diese Suffixe beschreibenden Blätter finden sich in zwei unterschiedlichen Zweigen des Teilbaumes zu t. Stefan Edelkamp Suffixbäume 7 Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Angenommen, der Knoten t wird durch die Kontraktion gelöscht. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Angenommen, der Knoten t wird durch die Kontraktion gelöscht. Dann hat t nur einen Nachfolger t0, der eine Erweiterung p0 von p repräsentiert. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Angenommen, der Knoten t wird durch die Kontraktion gelöscht. Dann hat t nur einen Nachfolger t0, der eine Erweiterung p0 von p repräsentiert. Die Zeichenkette p0 ist jedoch Präfix von sufi und sufj , was im Widerspruch dazu steht, dass p der größte gemeinsame Präfix ist. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Angenommen, der Knoten t wird durch die Kontraktion gelöscht. Dann hat t nur einen Nachfolger t0, der eine Erweiterung p0 von p repräsentiert. Die Zeichenkette p0 ist jedoch Präfix von sufi und sufj , was im Widerspruch dazu steht, dass p der größte gemeinsame Präfix ist. Analog führt man die Annahme, dass sich sufi und sufj in einem Zweig des Teilbaumes zu t befinden, zu einem Widerspruch. Beweis: Der größte gemeinsame Präfix p zweier Suffixe sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen p beschreibenden Knoten t im Suffixtrie. Die die Suffixe sufi und sufj darstellenden Blätter befinden sich aufgrund der Präfixeigenschaft von p in dem Teilbaum, der durch t beschrieben wird. Angenommen, der Knoten t wird durch die Kontraktion gelöscht. Dann hat t nur einen Nachfolger t0, der eine Erweiterung p0 von p repräsentiert. Die Zeichenkette p0 ist jedoch Präfix von sufi und sufj , was im Widerspruch dazu steht, dass p der größte gemeinsame Präfix ist. Analog führt man die Annahme, dass sich sufi und sufj in einem Zweig des Teilbaumes zu t befinden, zu einem Widerspruch. Stefan Edelkamp Suffixbäume 8 Konstruktion von Suffix-Bäumen Unterschiedliche Konstruktionsalgorithmen für den Suffixbaum wurden angegeben. Konstruktion von Suffix-Bäumen Unterschiedliche Konstruktionsalgorithmen für den Suffixbaum wurden angegeben. Die Algorithmen von Slisenko et al. und Chen et al. beruhen auf den Indexgedanken Weiners, während McCreight eine speicherplatzfreundliche Konstruktion des Suffixbaumes vorschlägt. Konstruktion von Suffix-Bäumen Unterschiedliche Konstruktionsalgorithmen für den Suffixbaum wurden angegeben. Die Algorithmen von Slisenko et al. und Chen et al. beruhen auf den Indexgedanken Weiners, während McCreight eine speicherplatzfreundliche Konstruktion des Suffixbaumes vorschlägt. Sie fußt auf dem sogenannten Suffixlink. Der Suffixlink von dem Ort einer Zeichenkette aα, a ∈ Σ, α ∈ Σ∗ zeigt auf den Ort von α und wird als als Abkürzung bei der Baumkonstruktion verwendet werden. Konstruktion von Suffix-Bäumen Unterschiedliche Konstruktionsalgorithmen für den Suffixbaum wurden angegeben. Die Algorithmen von Slisenko et al. und Chen et al. beruhen auf den Indexgedanken Weiners, während McCreight eine speicherplatzfreundliche Konstruktion des Suffixbaumes vorschlägt. Sie fußt auf dem sogenannten Suffixlink. Der Suffixlink von dem Ort einer Zeichenkette aα, a ∈ Σ, α ∈ Σ∗ zeigt auf den Ort von α und wird als als Abkürzung bei der Baumkonstruktion verwendet werden. Während McCreight den Suffixbaum von dem längsten zu dem kürzesten String konstruiert, schlägt Ukkonen einen Linearzeitalgorithmus für den gegenteiligen Aufbau vor. Konstruktion von Suffix-Bäumen Unterschiedliche Konstruktionsalgorithmen für den Suffixbaum wurden angegeben. Die Algorithmen von Slisenko et al. und Chen et al. beruhen auf den Indexgedanken Weiners, während McCreight eine speicherplatzfreundliche Konstruktion des Suffixbaumes vorschlägt. Sie fußt auf dem sogenannten Suffixlink. Der Suffixlink von dem Ort einer Zeichenkette aα, a ∈ Σ, α ∈ Σ∗ zeigt auf den Ort von α und wird als als Abkürzung bei der Baumkonstruktion verwendet werden. Während McCreight den Suffixbaum von dem längsten zu dem kürzesten String konstruiert, schlägt Ukkonen einen Linearzeitalgorithmus für den gegenteiligen Aufbau vor. Stefan Edelkamp Suffixbäume 9 Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; for i := 0 to n − 1 do Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; for i := 0 to n − 1 do füge sufi+ in Ti ein; Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; for i := 0 to n − 1 do füge sufi+ in Ti ein; end for end; Naives Verfahren In dem ersten Ansatz beginnen wir mit dem leeren Baum T0. Der Baum Ti+1 entsteht aus Ti durch Einfügen des Suffixes sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; for i := 0 to n − 1 do füge sufi+ in Ti ein; end for end; Stefan Edelkamp Suffixbäume 10 Satz 3 Es ist headi der längste Präfix von sufi, dessen erweiterter Ort in Ti−1 existiert. Satz 3 Es ist headi der längste Präfix von sufi, dessen erweiterter Ort in Ti−1 existiert. Beweis: In Ti haben alle Suffixe sufj , j < i bereits einen Ort. Satz 3 Es ist headi der längste Präfix von sufi, dessen erweiterter Ort in Ti−1 existiert. Beweis: In Ti haben alle Suffixe sufj , j < i bereits einen Ort. Stefan Edelkamp Suffixbäume 11 Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: 1. Man bestimme den erweiterten Ort von headi+1 in Ti und teile die letzte zu diesem Ort führende Kante in zwei neue Kanten auf durch Einfügen eines neuen Knotens. Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: 1. Man bestimme den erweiterten Ort von headi+1 in Ti und teile die letzte zu diesem Ort führende Kante in zwei neue Kanten auf durch Einfügen eines neuen Knotens. 2. Man schaffe ein neues Blatt als Ort für sufi+. Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: 1. Man bestimme den erweiterten Ort von headi+1 in Ti und teile die letzte zu diesem Ort führende Kante in zwei neue Kanten auf durch Einfügen eines neuen Knotens. 2. Man schaffe ein neues Blatt als Ort für sufi+. Offenbar sichert das eindeutige Endesymbol $, dass stets taili 6= ε ist. Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: 1. Man bestimme den erweiterten Ort von headi+1 in Ti und teile die letzte zu diesem Ort führende Kante in zwei neue Kanten auf durch Einfügen eines neuen Knotens. 2. Man schaffe ein neues Blatt als Ort für sufi+. Offenbar sichert das eindeutige Endesymbol $, dass stets taili 6= ε ist. headi+1 v x = erweiterter Ort von headi+1 Stefan Edelkamp Suffixbäume taili+1 x 12 T3 T2 Beispiel 3 ababc head3 = ab tail3 = c ab babc abc babc c T3 T2 Beispiel 3 ababc head3 = ab tail3 = c ab babc abc babc c Es gibt Beispiele, für die der oben beschriebene Algorithmus Ω(n2) viele Schritte benötigt, um einen Suffixbaum zu konstruieren. T3 T2 Beispiel 3 ababc ab babc abc head3 = ab tail3 = c babc c Es gibt Beispiele, für die der oben beschriebene Algorithmus Ω(n2) viele Schritte benötigt, um einen Suffixbaum zu konstruieren. Stefan Edelkamp Suffixbäume 13 Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter Zeit geschehen. Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter Zeit geschehen. Der Algorithmus läuft in 2 Phasen. Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter Zeit geschehen. Der Algorithmus läuft in 2 Phasen. 1. Bestimme headi+1 in konstanter amortisierter Zeit in Ti Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter Zeit geschehen. Der Algorithmus läuft in 2 Phasen. 1. Bestimme headi+1 in konstanter amortisierter Zeit in Ti 2. Füge zusätzliche Suffixlinks ein Der Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte. Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter Zeit geschehen. Der Algorithmus läuft in 2 Phasen. 1. Bestimme headi+1 in konstanter amortisierter Zeit in Ti 2. Füge zusätzliche Suffixlinks ein Stefan Edelkamp Suffixbäume 14 Lemma 1 Wenn headi = aγ für ein Symbol a und eine (evtl. leere) Zeichenkette γ ist, dann ist γ ein Präfix von headi+1. Lemma 1 Wenn headi = aγ für ein Symbol a und eine (evtl. leere) Zeichenkette γ ist, dann ist γ ein Präfix von headi+1. Beweis: Sei headi = aγ, dann existiert ein j < i, so dass aγ Präfix von sufi und sufj ist nach der Definition von headi. Also ist γ ein Präfix sowohl von sufi+ als auch von sufj+. Lemma 1 Wenn headi = aγ für ein Symbol a und eine (evtl. leere) Zeichenkette γ ist, dann ist γ ein Präfix von headi+1. Beweis: Sei headi = aγ, dann existiert ein j < i, so dass aγ Präfix von sufi und sufj ist nach der Definition von headi. Also ist γ ein Präfix sowohl von sufi+ als auch von sufj+. Stefan Edelkamp Suffixbäume 15 Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. (I2) Bei der Konstruktion von Ti wird der kontraktierte Ort von headi in Ti−1 besucht. Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. (I2) Bei der Konstruktion von Ti wird der kontraktierte Ort von headi in Ti−1 besucht. Offensichtlich gelten beide Bedingungen für i = 1. Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. (I2) Bei der Konstruktion von Ti wird der kontraktierte Ort von headi in Ti−1 besucht. Offensichtlich gelten beide Bedingungen für i = 1.Ist i > 1, so folgt aus (I2), dass man die Konstruktion von Ti+1 aus Ti beim kontraktierten Ort von headi in Ti−1 beginnen kann. Man beachte, dass der Ort von γ niemals im Teilbaum mit Wurzel beim Ort von aγ liegen kann, da in diesem Teilbaum nur Erweiterungen von aγ liegen. Invarianten des Algorithmus’: (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. (I2) Bei der Konstruktion von Ti wird der kontraktierte Ort von headi in Ti−1 besucht. Offensichtlich gelten beide Bedingungen für i = 1.Ist i > 1, so folgt aus (I2), dass man die Konstruktion von Ti+1 aus Ti beim kontraktierten Ort von headi in Ti−1 beginnen kann. Stefan Edelkamp Suffixbäume 16 Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Ferner sei βi = headi − aiαi, Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Ferner sei βi = headi − aiαi, d.h. headi = aiαiβi. Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Ferner sei βi = headi − aiαi, d.h. headi = aiαiβi.Ist headi 6= ε, haben wir in Ti: Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Ferner sei βi = headi − aiαi, d.h. headi = aiαiβi.Ist headi 6= ε, haben wir in Ti: headi αi ai αi v0 u βi w γi+1 x y βi v sufi v 0 = kontraktierter Ort von headi in Ti−1 v = Ort von headi in Ti einzufügender Suffix-Zeiger für headi Aufgrund des obigen Lemmas ist headi+1 = αiβiγi+1. Definition 3 Ist headi 6= ε, so bezeichnet αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. Ferner sei βi = headi − aiαi, d.h. headi = aiαiβi.Ist headi 6= ε, haben wir in Ti: headi αi ai αi v0 u βi w γi+1 x y βi v sufi v 0 = kontraktierter Ort von headi in Ti−1 v = Ort von headi in Ti einzufügender Suffix-Zeiger für headi Aufgrund des obigen Lemmas ist headi+1 = αiβiγi+1. Stefan Edelkamp Suffixbäume 17 Von dem kontraktierten Ort v 0 von headi gibt es bereits einen korrekten Suffix-Zeiger in Ti zu einem Knoten u nach (I1). Von dem kontraktierten Ort v 0 von headi gibt es bereits einen korrekten Suffix-Zeiger in Ti zu einem Knoten u nach (I1). Zur Konstruktion des Ortes von headi+1 in Ti (und damit zur Konstruktion von Ti+1) startet man bei u anstatt bei der Wurzel von Ti wie bei dem naiven Verfahren. Von dem kontraktierten Ort v 0 von headi gibt es bereits einen korrekten Suffix-Zeiger in Ti zu einem Knoten u nach (I1). Zur Konstruktion des Ortes von headi+1 in Ti (und damit zur Konstruktion von Ti+1) startet man bei u anstatt bei der Wurzel von Ti wie bei dem naiven Verfahren. Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Scan γi+1 ausgehend von w, d.h. folge einem Weg in Ti ausgehend von w, dessen Kantenbeschriftungen mit sufi+ übereinstimmen, bis man aus dem Baum bei der Kante (x, y) herausfällt. Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Scan γi+1 ausgehend von w, d.h. folge einem Weg in Ti ausgehend von w, dessen Kantenbeschriftungen mit sufi+ übereinstimmen, bis man aus dem Baum bei der Kante (x, y) herausfällt. 2. Falls der Ort w von αiβi in Ti nicht existiert, Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Scan γi+1 ausgehend von w, d.h. folge einem Weg in Ti ausgehend von w, dessen Kantenbeschriftungen mit sufi+ übereinstimmen, bis man aus dem Baum bei der Kante (x, y) herausfällt. 2. Falls der Ort w von αiβi in Ti nicht existiert,sei x der kontraktierte Ort von αiβi und y der erweiterte Ort von αiβi. Es ist headi+1 = αiβi (s.u.). Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Scan γi+1 ausgehend von w, d.h. folge einem Weg in Ti ausgehend von w, dessen Kantenbeschriftungen mit sufi+ übereinstimmen, bis man aus dem Baum bei der Kante (x, y) herausfällt. 2. Falls der Ort w von αiβi in Ti nicht existiert,sei x der kontraktierte Ort von αiβi und y der erweiterte Ort von αiβi. Es ist headi+1 = αiβi (s.u.). 3. Schaffe bei (x, y) einen inneren Knoten z für den Ort von headi+1 und ein Blatt für den Ort von sufi+. Abbildung 3 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu dem Knoten u. 2. Falls βi 6= ε, rescan βi in Ti, d.h. folge einem Weg in Ti ausgehend von u, dessen Kantenbeschriftungen βi ergeben. 1. Falls der Ort w von αiβi in Ti existiert, Scan γi+1 ausgehend von w, d.h. folge einem Weg in Ti ausgehend von w, dessen Kantenbeschriftungen mit sufi+ übereinstimmen, bis man aus dem Baum bei der Kante (x, y) herausfällt. 2. Falls der Ort w von αiβi in Ti nicht existiert,sei x der kontraktierte Ort von αiβi und y der erweiterte Ort von αiβi. Es ist headi+1 = αiβi (s.u.). 3. Schaffe bei (x, y) einen inneren Knoten z für den Ort von headi+1 und ein Blatt für den Ort von sufi+. Stefan Edelkamp Suffixbäume 18 Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. 1. Folge Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu u. Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. 1. Folge Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu u. 2. Falls βi 6= ε, rescan βi in Ti bis zum Ort w von αiβi. Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. 1. Folge Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu u. 2. Falls βi 6= ε, rescan βi in Ti bis zum Ort w von αiβi. Setze den Suffix-Zeiger des Ortes v von headi auf w. Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. 1. Folge Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu u. 2. Falls βi 6= ε, rescan βi in Ti bis zum Ort w von αiβi. Setze den Suffix-Zeiger des Ortes v von headi auf w. In einer Implementation werden natürlich Schritt 1 und 2 in einander verflochten. Schritt 2: Einfügen des Suffix-Zeigers für den Ort v von headi. 1. Folge Suffix-Zeiger von dem kontraktierten Ort v 0 von headi zu u. 2. Falls βi 6= ε, rescan βi in Ti bis zum Ort w von αiβi. Setze den Suffix-Zeiger des Ortes v von headi auf w. In einer Implementation werden natürlich Schritt 1 und 2 in einander verflochten. headi : headi+1 : ai αi βi αi βi u γi+1 w Phase II Rescanning“ Phase III ” Scanning“ ” Lemma 2 Falls der Ort von αiβi in Ti nicht existiert, dann ist headi+1 = αiβi, d.h. γ[i + 1] = ε. headi : headi+1 : ai αi βi αi βi u γi+1 w Phase II Rescanning“ Phase III ” Scanning“ ” Lemma 2 Falls der Ort von αiβi in Ti nicht existiert, dann ist headi+1 = αiβi, d.h. γ[i + 1] = ε. Stefan Edelkamp Suffixbäume 19 Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. Also ist j < i + 1 und sufj hat das Präfix αiβi Somit hat sufj den Präfix αiβiδ2. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. Also ist j < i + 1 und sufj hat das Präfix αiβi Somit hat sufj den Präfix αiβiδ2. Wir zeigen: Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. Also ist j < i + 1 und sufj hat das Präfix αiβi Somit hat sufj den Präfix αiβiδ2. Wir zeigen: sufj = αiβia · · · und sufi+ = αiβib · · · mit a 6= b. Beweis: Sei v der kontraktierte und w der erweiterte Ort von αiβi. Die Beschriftung der Kanten des Weges zu v sei gleich γ und die Beschriftung von (v, w) gleich δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi. D.h. 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. Also ist j < i + 1 und sufj hat das Präfix αiβi Somit hat sufj den Präfix αiβiδ2. Wir zeigen: sufj = αiβia · · · und sufi+ = αiβib · · · mit a 6= b. Stefan Edelkamp Suffixbäume 20 Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. ⇒ Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. ⇒ Längstes gemeinsames Präfix: Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. ⇒ Längstes gemeinsames Präfix: αiβi. Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 ⇒ sufj 0 hat Präfix aiαiβiδ2 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. ⇒ Längstes gemeinsames Präfix: αiβi. Beispiel 4 W = b5abab3a2b5c. Konstruktion von T14 aus T13 durch Einfügen von suf = bbbbbc in T13. Beispiel 4 W = b5abab3a2b5c. Konstruktion von T14 aus T13 durch Einfügen von suf = bbbbbc in T13. a u b a... a b b v0 b a bb w a... v bbc head13 a x b a ba... a y head13 = a|b|bb head14 = b|bb|.?. suf = bbbbbc x z b c w b a a... y Ort von head14 suf Stefan Edelkamp Suffixbäume 21 Analyse Nun analysieren wir die Anzahl der Schritte, die der Algorithmus von McCreight benötigt. Analyse Nun analysieren wir die Anzahl der Schritte, die der Algorithmus von McCreight benötigt. Satz 4 Algorithmus von McCreight liefert in Zeit O(|W |) einen Suffixbaum für W . Analyse Nun analysieren wir die Anzahl der Schritte, die der Algorithmus von McCreight benötigt. Satz 4 Algorithmus von McCreight liefert in Zeit O(|W |) einen Suffixbaum für W . Stefan Edelkamp Suffixbäume 22 Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Analyse Rescannen Da αiβi ein Präfix von headi+1 ist, muss an einer Kante nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen. Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Analyse Rescannen Da αiβi ein Präfix von headi+1 ist, muss an einer Kante nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen. Demnach haben wir konstante Zeit pro besuchte Kante und die Anzahl der Schritte beim Rescannen ist proportional zur Anzahl der besuchten Kanten. Sei Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Analyse Rescannen Da αiβi ein Präfix von headi+1 ist, muss an einer Kante nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen. Demnach haben wir konstante Zeit pro besuchte Kante und die Anzahl der Schritte beim Rescannen ist proportional zur Anzahl der besuchten Kanten. Sei resi = βi−1γitaili. Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Analyse Rescannen Da αiβi ein Präfix von headi+1 ist, muss an einer Kante nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen. Demnach haben wir konstante Zeit pro besuchte Kante und die Anzahl der Schritte beim Rescannen ist proportional zur Anzahl der besuchten Kanten. Sei resi = βi−1γitaili. (res steht für Zeichen, die regescannt werden können). Beweis: In jeden Schritt wird ein Suffix von W gescannt und regescannt. Analyse Rescannen Da αiβi ein Präfix von headi+1 ist, muss an einer Kante nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen. Demnach haben wir konstante Zeit pro besuchte Kante und die Anzahl der Schritte beim Rescannen ist proportional zur Anzahl der besuchten Kanten. Sei resi = βi−1γitaili. (res steht für Zeichen, die regescannt werden können). Stefan Edelkamp Suffixbäume 23 Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Also n X i=1 ki ≤ Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Also n X i=1 ki ≤ n X i=1 |resi| − |resi+1| = Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Also n X i=1 ki ≤ n X i=1 |resi| − |resi+1| = |res1| − |resn+1| Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Also n X i=1 ki ≤ n X i=1 |resi| − |resi+1| = |res1| − |resn+1| ≤ n. Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1, folgt: |resi+1| ≤ |resi| − ki mit ki als Anzahl regesannte Kanten in Schritt i. Also n X i=1 ki ≤ n X |resi| − |resi+1| = |res1| − |resn+1| ≤ n. i=1 Somit ist die Gesamtanzahl regesannter Kanten durch n beschränkt. Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . Also ist die Gesamtanzahl gescannter Zeichen gleich Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . Also ist die Gesamtanzahl gescannter Zeichen gleich n−1 X i=0 |γi+1| = Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . Also ist die Gesamtanzahl gescannter Zeichen gleich n−1 X i=0 |γi+1| = n−1 X i=0 |headi+1| − |headi| + 1 = Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . Also ist die Gesamtanzahl gescannter Zeichen gleich n−1 X i=0 |γi+1| = n−1 X i=0 |headi+1| − |headi| + 1 = n + |headn| − |head0| = Analyse Scannen Die Anzahl gescannter Zeichen in Schritt i ist gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . Also ist die Gesamtanzahl gescannter Zeichen gleich n−1 X i=0 |γi+1| = n−1 X i=0 |headi+1| − |headi| + 1 = n + |headn| − |head0| = n. Beispiel 5 Suffixbaum für bbabaabc: Beispiel 5 Suffixbaum für bbabaabc: T0 suf 1 T1 bbabaabc T2 b bbabaabc abaabc babaabc suf 2 babaabc head 2 b suf 3 abaabc head 3 ε Beispiel 5 Suffixbaum für bbabaabc: T0 T1 suf 1 T2 b bbabaabc bbabaabc abaabc babaabc suf 2 babaabc head 2 b suf 3 abaabc head 3 ε T3 abaabc abaabc T4 abaabc b babaabc babaabc a abc suf 4 baabc head 4 ba a4 b α4 ε β4 b baabc Ort von head 4 a suf 5 aabc head 5 a a5 a α5 ε β5 ε Beispiel 5 Suffixbaum für bbabaabc: T0 T1 suf 1 T2 b bbabaabc bbabaabc abaabc babaabc suf 2 babaabc head 2 b suf 3 abaabc head 3 ε T3 abaabc abaabc T4 abaabc b babaabc Stefan Edelkamp Suffixbäume babaabc a abc suf 4 baabc head 4 ba a4 b α4 ε β4 b baabc Ort von head 4 a suf 5 aabc head 5 a a5 a α5 ε 24 β5 ε T5 T6 b babaabc a abc baabc abc a baabc abc b a c babaabc a b aabc abc baabc Ort von head 5 suf 6 abc head 6 ab a6 a α6 ε β6 b suf 7 bc head 7 b a7 b α7 Ort von head 6 ε β7 b T5 T6 b babaabc a abc baabc abc a c babaabc a b baabc abc b a aabc abc baabc Ort von head 5 suf 6 abc head 6 ab a6 a α6 ε β6 b T7 abc suf 8 a c b c c T8 babaabc b a suf 7 bc head 7 b a7 b α7 aabc abc baabc a abc Ort von head 6 ε c b babaabc b a c b c β7 aabc abc baabc Verwendung von Suffix-Bäumen: Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. 3. Suche längstes, doppelt auftretendes Wort: Finde Ort eines Wortes mit größter gewichteter Tiefe, der innerer Knoten ist. Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. 3. Suche längstes, doppelt auftretendes Wort: Finde Ort eines Wortes mit größter gewichteter Tiefe, der innerer Knoten ist. 4. Suche nach Präfix: Alle Vorkommen von Zeichenketten mit Präfix α finden sich in dem Teilbaum unterhalb des Ortes“ von α in T . ” Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. 3. Suche längstes, doppelt auftretendes Wort: Finde Ort eines Wortes mit größter gewichteter Tiefe, der innerer Knoten ist. 4. Suche nach Präfix: Alle Vorkommen von Zeichenketten mit Präfix α finden sich in dem Teilbaum unterhalb des Ortes“ von α in T . ” 5. Bereichssuche nach [α, β ] Verwendung von Suffix-Bäumen: 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. 3. Suche längstes, doppelt auftretendes Wort: Finde Ort eines Wortes mit größter gewichteter Tiefe, der innerer Knoten ist. 4. Suche nach Präfix: Alle Vorkommen von Zeichenketten mit Präfix α finden sich in dem Teilbaum unterhalb des Ortes“ von α in T . ” 5. Bereichssuche nach [α, β ] Stefan Edelkamp Suffixbäume 25 Generalisierte Suffix-Bäume Die Idee, McCreights Algorithmus zur Konstruktion eines Suffixbaumes auf mehrere Strings auszuweiten, stößt zuerst auf Widerstand. Generalisierte Suffix-Bäume Die Idee, McCreights Algorithmus zur Konstruktion eines Suffixbaumes auf mehrere Strings auszuweiten, stößt zuerst auf Widerstand. Zwar können der Suffixbaum S 0 und damit die Indizes aller unterschiedlichen Teilstrings von W1$1, . . . , Wk $k für die im Wörterbuch zu speichernden Strings W1, . . . , Wk nach McCreights Ansatz aufgebaut werden. Generalisierte Suffix-Bäume Die Idee, McCreights Algorithmus zur Konstruktion eines Suffixbaumes auf mehrere Strings auszuweiten, stößt zuerst auf Widerstand. Zwar können der Suffixbaum S 0 und damit die Indizes aller unterschiedlichen Teilstrings von W1$1, . . . , Wk $k für die im Wörterbuch zu speichernden Strings W1, . . . , Wk nach McCreights Ansatz aufgebaut werden. Doch ist die Struktur dann ein für allemal festgelegt und müßte, wie die Fehlerfunktion im Algorithmus von Aho und Corasick, für jede Einfüge- und Löschoperation immer wieder erneut berechnet werden. Generalisierte Suffix-Bäume Die Idee, McCreights Algorithmus zur Konstruktion eines Suffixbaumes auf mehrere Strings auszuweiten, stößt zuerst auf Widerstand. Zwar können der Suffixbaum S 0 und damit die Indizes aller unterschiedlichen Teilstrings von W1$1, . . . , Wk $k für die im Wörterbuch zu speichernden Strings W1, . . . , Wk nach McCreights Ansatz aufgebaut werden. Doch ist die Struktur dann ein für allemal festgelegt und müßte, wie die Fehlerfunktion im Algorithmus von Aho und Corasick, für jede Einfüge- und Löschoperation immer wieder erneut berechnet werden. Stefan Edelkamp Suffixbäume 26 Auf der anderen Seite kann der Patricia–Baum S für alle Endstücke der Zeichenketten W1$1 bis Wk $k konstruiert werden. Auf der anderen Seite kann der Patricia–Baum S für alle Endstücke der Zeichenketten W1$1 bis Wk $k konstruiert werden. 0 $ 1 $ $ 10 (1100110$,7,7) (1011001$,7,7) (10101$,5,5) ... 1 01 0 $ $ $ $ 01 01 1 01$ 01$ $ 10$ 1 01$ $ $ $ 1001$ Abbildung 4 Stefan Edelkamp Suffixbäume 10 27 10$ 0 10$ Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Um ein unbeschränktes Alphabet zu vermeiden, beschreiben wir mit $ jedes der $i, lassen jedoch den Vergleich von $ mit sich selbst scheitern. Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Um ein unbeschränktes Alphabet zu vermeiden, beschreiben wir mit $ jedes der $i, lassen jedoch den Vergleich von $ mit sich selbst scheitern. Die Anzahl der Knoten in S ist durch die Summe D beschränkt. Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Um ein unbeschränktes Alphabet zu vermeiden, beschreiben wir mit $ jedes der $i, lassen jedoch den Vergleich von $ mit sich selbst scheitern. Die Anzahl der Knoten in S ist durch die Summe D beschränkt. Es ist nicht schwer, McCreights Algorithmus auf das Einfügen eines Musters im generaliserten Suffixbaum mit Laufzeit O(|W |) zu erweitern. Es ist der Verdienst von Amir et al. zu erkennen, dass die Baumstrukturen von S und S 0 isomorph sind und dass die Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten übereinstimmen. Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Um ein unbeschränktes Alphabet zu vermeiden, beschreiben wir mit $ jedes der $i, lassen jedoch den Vergleich von $ mit sich selbst scheitern. Die Anzahl der Knoten in S ist durch die Summe D beschränkt. Es ist nicht schwer, McCreights Algorithmus auf das Einfügen eines Musters im generaliserten Suffixbaum mit Laufzeit O(|W |) zu erweitern. Stefan Edelkamp Suffixbäume 28 Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Satz 5 Sei M die Menge der gespeicherten Zeichenketten im Suffixbaum S und sei T der Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Satz 5 Sei M die Menge der gespeicherten Zeichenketten im Suffixbaum S und sei T der Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. Dann gibt es eine Bijektion zwischen der Menge der Knoten in T (mit Ausnahme der Wurzel) in die Menge der Blattknoten von S. Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Satz 5 Sei M die Menge der gespeicherten Zeichenketten im Suffixbaum S und sei T der Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. Dann gibt es eine Bijektion zwischen der Menge der Knoten in T (mit Ausnahme der Wurzel) in die Menge der Blattknoten von S. Beweis: Auf der einen Seite entspricht jedem Suffix der Zeichenkette Wi ein Blatt in S. Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Satz 5 Sei M die Menge der gespeicherten Zeichenketten im Suffixbaum S und sei T der Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. Dann gibt es eine Bijektion zwischen der Menge der Knoten in T (mit Ausnahme der Wurzel) in die Menge der Blattknoten von S. Beweis: Auf der einen Seite entspricht jedem Suffix der Zeichenkette Wi ein Blatt in S. Auf der anderen Seite existiert für jeden Präfix von WiR ein Knoten in T . Probleme bereitet jedoch das Löschen von Strings. Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Satz 5 Sei M die Menge der gespeicherten Zeichenketten im Suffixbaum S und sei T der Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. Dann gibt es eine Bijektion zwischen der Menge der Knoten in T (mit Ausnahme der Wurzel) in die Menge der Blattknoten von S. Beweis: Auf der einen Seite entspricht jedem Suffix der Zeichenkette Wi ein Blatt in S. Auf der anderen Seite existiert für jeden Präfix von WiR ein Knoten in T . Stefan Edelkamp Suffixbäume 29 Beispiel 6 Abbildung 5 zeigt eine Momentaufnahme der Einfügung des Strings 11010$ in den generalisierten Suffixbaum mit assoziierten inversen Trie. Beispiel 6 Abbildung 5 zeigt eine Momentaufnahme der Einfügung des Strings 11010$ in den generalisierten Suffixbaum mit assoziierten inversen Trie. 0 1 $ 0 1 01 10 0 $ $ 1 10 $ $ 0 2 10 9 $ 01 1 20 10$ $ 3 0 $ $ $ 13 10$ 01 01$ 01$ 8 $ 1$ 4 5 16 10$ $ $ 18 1$ 19 10$ 1001$ 15 17 11 6 12 7 14 1 1 0 1 1 1 2 20 19 18 3 0 4 0 5 1 6 1 7 0 $ 0 1 Abbildung 5 Stefan Edelkamp Suffixbäume 8 0 0 10 1 11 1 12 9 1 15 0 16 30 1 17 0 13 1 14 Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Dann sind die Suffixlinks nach jedem einzelnen Löschschritt im Suffixbaum korrekt. Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Dann sind die Suffixlinks nach jedem einzelnen Löschschritt im Suffixbaum korrekt. Das von Amir et al. vernachlässigte Problem ist, dass der entfernte String noch gebraucht werden kann. Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Dann sind die Suffixlinks nach jedem einzelnen Löschschritt im Suffixbaum korrekt. Das von Amir et al. vernachlässigte Problem ist, dass der entfernte String noch gebraucht werden kann. Die Grundidee der vorgeschlagenen Verbesserung ist es, die durch T eindeutig festgelegte Repräsentation an den Blättern auf die inneren Knoten zu übertragen. Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Dann sind die Suffixlinks nach jedem einzelnen Löschschritt im Suffixbaum korrekt. Das von Amir et al. vernachlässigte Problem ist, dass der entfernte String noch gebraucht werden kann. Die Grundidee der vorgeschlagenen Verbesserung ist es, die durch T eindeutig festgelegte Repräsentation an den Blättern auf die inneren Knoten zu übertragen. Deshalb führen wir Zwillinge ein, die die Historie der Blattgenerierungen beschreiben. Durch den assoziierten Trie ist es möglich die Strings vom längsten Suffix zum kürzesten Suffix zu löschen. Dann sind die Suffixlinks nach jedem einzelnen Löschschritt im Suffixbaum korrekt. Das von Amir et al. vernachlässigte Problem ist, dass der entfernte String noch gebraucht werden kann. Die Grundidee der vorgeschlagenen Verbesserung ist es, die durch T eindeutig festgelegte Repräsentation an den Blättern auf die inneren Knoten zu übertragen. Deshalb führen wir Zwillinge ein, die die Historie der Blattgenerierungen beschreiben. Stefan Edelkamp Suffixbäume 31 Beispiel 7 Abbildung 6 stellt die entsprechende Rückverzeigerung graphisch dar. Beispiel 7 Abbildung 6 stellt die entsprechende Rückverzeigerung graphisch dar. 0 1 $ 0 1 01 0 $ $ 1 $ $ 10 9 01$ 01$ 13 Abbildung 6 Stefan Edelkamp Suffixbäume 2 01 1 3 1 $ $ 01$ 5 $ 01 10$ $ 4 16 8 $ 10 10 $ 1001$ 17 14 32 15 10$ 0 6 10$ 11 7 12 Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. In dem generalisierten Suffixbaum gilt die folgende Invarianz: Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. In dem generalisierten Suffixbaum gilt die folgende Invarianz: (Ia) Für alle inneren Knoten p aus I existiert ein Blattknoten q aus L der zugleich Zwillingsnachfolger von p ist (q ∈ Γ0(p)) und dessen Stringrepräsentation mit p übereinstimmt. Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. In dem generalisierten Suffixbaum gilt die folgende Invarianz: (Ia) Für alle inneren Knoten p aus I existiert ein Blattknoten q aus L der zugleich Zwillingsnachfolger von p ist (q ∈ Γ0(p)) und dessen Stringrepräsentation mit p übereinstimmt. (Ib) Für alle inneren Knoten p aus I gilt: Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. In dem generalisierten Suffixbaum gilt die folgende Invarianz: (Ia) Für alle inneren Knoten p aus I existiert ein Blattknoten q aus L der zugleich Zwillingsnachfolger von p ist (q ∈ Γ0(p)) und dessen Stringrepräsentation mit p übereinstimmt. (Ib) Für alle inneren Knoten p aus I gilt: |Γ0(p)| = |Γ(p)| − 1, Satz 6 Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. In dem generalisierten Suffixbaum gilt die folgende Invarianz: (Ia) Für alle inneren Knoten p aus I existiert ein Blattknoten q aus L der zugleich Zwillingsnachfolger von p ist (q ∈ Γ0(p)) und dessen Stringrepräsentation mit p übereinstimmt. (Ib) Für alle inneren Knoten p aus I gilt: |Γ0(p)| = |Γ(p)| − 1, d.h. die Anzahl der direkten Nachfolger ist immer um eins größer als die Anzahl der Zwillingsnachfolger. Stefan Edelkamp Suffixbäume 33 Satz 7 Sei S der generalisierten Suffixbaum nach einer beliebigen Anzahl von Einfüge- und Löschoperationen gespeichert sind und D die Summe der Längen aller Strings aus M . Satz 7 Sei S der generalisierten Suffixbaum nach einer beliebigen Anzahl von Einfüge- und Löschoperationen gespeichert sind und D die Summe der Längen aller Strings aus M . Dann ist der benötigte Speicherplatz im S durch O(D) beschränkt. Satz 7 Sei S der generalisierten Suffixbaum nach einer beliebigen Anzahl von Einfüge- und Löschoperationen gespeichert sind und D die Summe der Längen aller Strings aus M . Dann ist der benötigte Speicherplatz im S durch O(D) beschränkt. Jede Einzeloperation mit Wort W benötigt Zeit O(|W |) Stefan Edelkamp Suffixbäume 34 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T = T [1] T [2] . . . T [n] ∈ Σn Text 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T sufi = T [1] T [2] . . . T [n] ∈ Σn Text = T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T sufi T [i, j] = T [1] T [2] . . . T [n] ∈ Σn Text = T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) = T [max(1, i)..min(j, n)] Teilwort 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T sufi T [i, j] pos = T [1] T [2] . . . T [n] ∈ Σn Text = T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) = T [max(1, i)..min(j, n)] Teilwort = [i1, . . . , in] mit pos[k] ∈ {1, . . . , n} und 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T = sufi = T [i, j] = pos = sufpos[k] = T [1] T [2] . . . T [n] ∈ Σn Text T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) T [max(1, i)..min(j, n)] Teilwort mit pos[k] ∈ {1, . . . , n} und [i1, . . . , in] das lexikographisch k-kleinste Suffix von T 2 Suffix-Arrays Ein Suffix-Array ist eine sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche. Definition 4 Sei T = sufi = T [i, j] = pos = sufpos[k] = T [1] T [2] . . . T [n] ∈ Σn Text T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) T [max(1, i)..min(j, n)] Teilwort mit pos[k] ∈ {1, . . . , n} und [i1, . . . , in] das lexikographisch k-kleinste Suffix von T mit sufpos[1] < sufpos[2] < · · · < sufpos[n]. Stefan Edelkamp Suffix-Arrays 35 Definition 5 Die Vergleichsrelation <p sei festgelegt durch A <p B :⇐⇒ A[1, p] < B[1, p] Definition 5 Die Vergleichsrelation <p sei festgelegt durch A <p B :⇐⇒ A[1, p] < B[1, p] (analog: =p, ≤p, >p, ≥p, 6=p) Definition 5 Die Vergleichsrelation <p sei festgelegt durch A <p B :⇐⇒ A[1, p] < B[1, p] (analog: =p, ≤p, >p, ≥p, 6=p) Satz 8 Suffix-Array suf mit Index pos ist bezl. ≤p sortiert, d.h. sufpos[1] ≤p sufpos[1] ≤p · · · ≤p sufpos[n] Beweis: Alle Präfixe zu einem gesuchten Anfang W mit Länge p liegen im pos-Array hintereinander. Stefan Edelkamp Suffix-Arrays 36 Suche die untere Grenze LW für das Vorkommen von Präfix W mit |W | = p im pos-Array: Suche die untere Grenze LW für das Vorkommen von Präfix W mit |W | = p im pos-Array: LW := min{k | W ≤p sufpos[k] ∨ k = n} durch binäre Suche nach LW im pos-Array. Suche die untere Grenze LW für das Vorkommen von Präfix W mit |W | = p im pos-Array: LW := min{k | W ≤p sufpos[k] ∨ k = n} durch binäre Suche nach LW im pos-Array. Stefan Edelkamp Suffix-Arrays 37 Beispiel 8 i T 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 a b a a b a b a a a b c a b b d $ Suchwort: W = aba Stefan Edelkamp Suffix-Arrays 38 k pos[k] sufpos[k] 1 8 aaa b ca b bd$ 2 3 aa ba baaa b ca b bd$ 3 9 aa b ca b bd$ 4 6 a baaa b ca b bd$ 5 1 a baa ba baaa b ca b bd$ 6 4 a ba baaa b ca b bd$ 7 13 a b b d $ 8 10 a b c a b b d $ 9 7 baaa b ca b bd$ 10 2 baa ba baaa b ca b bd$ 11 4 ba baaa b ca b bd$ 12 14 b b d $ 13 11 b c a b b d $ 14 15 b d $ 15 12 c a b b d $ 16 16 d $ 17 17 $ Algorithmus LW -search Input: Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 7 if W ≤p sufpos[M ] then R ← M Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 7 if W ≤p sufpos[M ] then R ← M 8 else L←M Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 7 if W ≤p sufpos[M ] then R ← M 8 else L←M 10 end while Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 7 if W ≤p sufpos[M ] then R ← M 8 else L←M 10 end while 11 LW ← R Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 2 else if W >p sufpos[n] 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 7 if W ≤p sufpos[M ] then R ← M 8 else L←M 10 end while 11 LW ← R 13 return LW Stefan Edelkamp Suffix-Arrays 39 Satz 9 Die Teilwortsuche in einem Suffix-Array ist in O(m log n) Zeit möglich. Satz 9 Die Teilwortsuche in einem Suffix-Array ist in O(m log n) Zeit möglich. Als Verbesserung von LW -search nutze die folgende Idee: Satz 9 Die Teilwortsuche in einem Suffix-Array ist in O(m log n) Zeit möglich. Als Verbesserung von LW -search nutze die folgende Idee: Spare Vergleiche zwischen Zeichen, deren Ergebnis bekannt ist. Satz 9 Die Teilwortsuche in einem Suffix-Array ist in O(m log n) Zeit möglich. Als Verbesserung von LW -search nutze die folgende Idee: Spare Vergleiche zwischen Zeichen, deren Ergebnis bekannt ist. Dazu definiere lcp(v, w) als Länge des längsten gemeinsamen Präfixes von v, w durch Satz 9 Die Teilwortsuche in einem Suffix-Array ist in O(m log n) Zeit möglich. Als Verbesserung von LW -search nutze die folgende Idee: Spare Vergleiche zwischen Zeichen, deren Ergebnis bekannt ist. Dazu definiere lcp(v, w) als Länge des längsten gemeinsamen Präfixes von v, w durch lcp(v, w) ← max{p | v =p w} Stefan Edelkamp Suffix-Arrays 40 In LW -search sei ` = lcp(sufpos[L], W ) zuerst: In LW -search sei In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} In LW -search sei Dann gilt: ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} Dann gilt: sufpos[L] =h W =h sufpos[R] In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} Dann gilt: sufpos[L] =h W =h sufpos[R] In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} Dann gilt: sufpos[L] =h W =h sufpos[R] Damit brauchen die h ersten Zeichen nicht mehr verglichen zu werden. In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} Dann gilt: sufpos[L] =h W =h sufpos[R] Damit brauchen die h ersten Zeichen nicht mehr verglichen zu werden. Das worst case-Verhalten wird nicht geändert. In LW -search sei ` = lcp(sufpos[L], W ) zuerst: ` = lcp(sufpos[1], W ) r = lcp(sufpos[R], W ) zuerst: r = lcp(sufpos[n], W ) h = min{`, r} Dann gilt: sufpos[L] =h W =h sufpos[R] Damit brauchen die h ersten Zeichen nicht mehr verglichen zu werden. Das worst case-Verhalten wird nicht geändert. (Beispiel: Suche cp−1b in an−2b) Stefan Edelkamp Suffix-Arrays 41 2. Verbesserung von LW -search 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays Llcp[M ] : 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays Llcp[M ] : lcp(sufpos[M ], sufpos[L]) 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays Llcp[M ] : lcp(sufpos[M ], sufpos[L]) Rlcp[M ] : 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays Llcp[M ] : lcp(sufpos[M ], sufpos[L]) Rlcp[M ] : lcp(sufpos[M ], sufpos[R]) 2. Verbesserung von LW -search Berechne und nutze Zusatzinformationen über Arrays Llcp[M ] : lcp(sufpos[M ], sufpos[L]) Rlcp[M ] : lcp(sufpos[M ], sufpos[R]) Stefan Edelkamp Suffix-Arrays 42 k=M 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 L Llcp pos[k] sufpos[k] 8 aaa b ca b bd$ 1 2 3 aa ba baaa b ca b bd$ 1 2 9 aa b ca b bd$ 3 1 6 a baaa b ca b bd$ 1 1 1 a baa ba baaa b c a b bd$ 5 3 4 a b a b a a a b c a b b d$ 5 2 13 a b bd$ 7 2 10 a b ca b bd$ 1 0 7 baaa b ca b bd$ 9 3 2 baa ba baaa b ca b bd$ 9 2 5 ba baaa b ca b bd $ 11 1 14 b bd$ 9 1 11 b ca b bd$ 13 1 15 bd$ 13 0 12 ca b bd$ 15 0 16 d$ 0 16 $ Nutzen von Llcp und Rlcp in LW -search: Nutzen von Llcp und Rlcp in LW -search: Sei H = max{l, r} Nutzen von Llcp und Rlcp in LW -search: Sei H = max{l, r} ∆H = Differenz in H am Anfang und Ende einer Iteration Im Folgenden sei o.B.d.A.: r ≤ l = H, Nutzen von Llcp und Rlcp in LW -search: Sei H = max{l, r} ∆H = Differenz in H am Anfang und Ende einer Iteration Im Folgenden sei o.B.d.A.: r ≤ l = H, d.h. Llcp wird benutzt. Nutzen von Llcp und Rlcp in LW -search: Sei H = max{l, r} ∆H = Differenz in H am Anfang und Ende einer Iteration Im Folgenden sei o.B.d.A.: r ≤ l = H, d.h. Llcp wird benutzt. Unterscheide 3 Fälle Nutzen von Llcp und Rlcp in LW -search: Sei H = max{l, r} ∆H = Differenz in H am Anfang und Ende einer Iteration Im Folgenden sei o.B.d.A.: r ≤ l = H, d.h. Llcp wird benutzt. Unterscheide 3 Fälle Stefan Edelkamp Suffix-Arrays 43 1. Llcp[M ] > l 1. Llcp[M ] > l ` r L M R 1. Llcp[M ] > l ` r L M sufpos[M ] =l+1 R 1. Llcp[M ] > l ` r L M R sufpos[M ] =l+1 sufpos[L] =l+1 1. Llcp[M ] > l ` r L M R sufpos[M ] =l+1 sufpos[L] =l+1 = W Stefan Edelkamp Suffix-Arrays 44 2. Llcp[M ] = l 2. Llcp[M ] = l ` r L M R 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W Vergleiche Zeichen l + 1, . . . , l + j bis sufpos[M ] = 6 l+j W 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W Vergleiche Zeichen l + 1, . . . , l + j bis sufpos[M ] = 6 l+j W LW liegt links (rechts), dann 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W Vergleiche Zeichen l + 1, . . . , l + j bis sufpos[M ] = 6 l+j W LW liegt links (rechts), dann r ← l + j − 1 (l ← l + j − 1) 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W Vergleiche Zeichen l + 1, . . . , l + j bis sufpos[M ] = 6 l+j W LW liegt links (rechts), dann r ← l + j − 1 (l ← l + j − 1) # Zeichenvergleiche: 2. Llcp[M ] = l ` r L M R sufpos[M ] =l W Vergleiche Zeichen l + 1, . . . , l + j bis sufpos[M ] = 6 l+j W LW liegt links (rechts), dann r ← l + j − 1 (l ← l + j − 1) # Zeichenvergleiche: ∆H + 1 3. Llcp[M ] < l 3. Llcp[M ] < l ` r L M R 3. Llcp[M ] < l ` r L M R W =l sufpos[L] und W =l0 sufpos[M ] mit l0 < l 3. Llcp[M ] < l ` r L M R W =l sufpos[L] und W =l0 sufpos[M ] mit l0 < l LW gehört in linke Hälfte, r ← Llcp[M ] Stefan Edelkamp Suffix-Arrays 45 Durch Nutzung von Llcp und Rlcp werden pro Iteration max ∆H + 1 Vergleiche benötigt. Durch Nutzung von Llcp und Rlcp werden pro Iteration max ∆H + 1 Vergleiche benötigt. P Mit i ∆Hi ≤ m folgt: Durch Nutzung von Llcp und Rlcp werden pro Iteration max ∆H + 1 Vergleiche benötigt. P Mit i ∆Hi ≤ m folgt: Satz 10 Die Teilwortsuche in einem Suffix-Array ist in O(m + log n) Zeit möglich. Durch Nutzung von Llcp und Rlcp werden pro Iteration max ∆H + 1 Vergleiche benötigt. P Mit i ∆Hi ≤ m folgt: Satz 10 Die Teilwortsuche in einem Suffix-Array ist in O(m + log n) Zeit möglich. Stefan Edelkamp Suffix-Arrays 46