SuffixarrayEin Suffixarray ist in der Informatik ein Array, das die Suffixe einer Zeichenkette in lexikographischer Reihenfolge angibt. BeispielBetrachte den String =
Dieser String hat zwölf Suffixe, die auch durch ihre Startposition
Der leere String ist lexikografisch kleiner als jedes Suffix von . Daher ist der Endmarker
Als Array dargestellt ergibt sich Wenn der Originalstring bekannt ist, kann jedes Suffix platzsparend durch den Index seines ersten Zeichens spezifiziert werden. Das Suffixarray ist ein Array dieser Indizes in lexikographischer Reihenfolge. Für den String Der Endmarker AlgorithmenEs gibt eine Vielzahl an Algorithmen, um aus einem gegebenen Text der Länge n ein Suffixarray zu konstruieren. Die dabei verwendeten Methoden zur Suffix-Sortierung lassen sich grob in drei Klassen einteilen: Iterative, Rekursive und Induzierte Sortierung. Iterative TeilsortierungDer einfachste Weg besteht darin, einen effizienten vergleichsbasierten Sortieralgorithmus zu verwenden, der höchstens Vergleiche benötigt. Da der Vergleich zweier Suffixe Zeit benötigt, beträgt die komplette Laufzeit dieses Verfahrens . Weiter entwickelte Algorithmen verbessern dies auf , indem sie die Ergebnisse von Teilvergleichen ausnutzen und somit redundante Vergleiche vermeiden. Dazu wird zunächst nur der erste Buchstabe jedes Suffixes betrachtet und daraus ein vorläufiger Suffixarray aufgebaut, der Suffixe mit gleichem Anfangsbuchstaben noch nicht untereinander sortiert hat. Suffixe mit unterschiedlichen Anfangsbuchstaben sind aber bereits in der richtigen Reihenfolge enthalten. In einem zweiten Schritt wird jede Gruppe von Suffixen mit gleichem Anfangsbuchstaben so sortiert, dass sie bezüglich der ersten beiden Anfangsbuchstaben korrekt sortiert sind. Der dritte Schritt sortiert alle Suffixgruppen mit zwei gleichen Anfangsbuchstaben so, dass sie bezüglich der ersten vier richtig sortiert sind, der vierte Schritt so, dass sie bezüglich der ersten acht richtig sortiert sind, und so weiter. Nach Schritten ist jedes Suffix vollständig richtig sortiert und der Suffixarray fertig aufgebaut. Jeder Teilschritt ist in Zeit möglich, so dass sich die Gesamtlaufzeit ergibt.[1] Zu dieser Klasse gehören der klassische Suffixarray-Algorithmus von Manber und Myers[2] sowie der in der Praxis deutlich effizientere Algorithmus von Larsson und Sadakane.[3] Rekursive AlgorithmenDiese Algorithmenklasse wird erst seit 2003 erforscht. Der Zeichen des Strings werden dazu in zwei Zeichenketten x und y aufgeteilt. Anschließend wird der Algorithmus rekursiv auf x aufgerufen. Mit dem dadurch berechneten Suffixarray von x kann der Suffixarray von y effizient berechnet („induziert“) werden. Da die Aufteilung in x und y bekannt ist, kann daraus der Suffixarray von abgelesen werden. Durch geschickte Wahl von x und y haben die meisten dieser Algorithmen eine Laufzeit von . Da Rekursion in der Praxis teuer ist, sind sie jedoch nicht immer zu bevorzugen.[1] Induzierte SortierungAuch hier wird mit einem bereits berechneten Suffixarray einer Zeichenkette x der Suffixarray einer Zeichenkette y effizient berechnet (induziert). Anstelle einer rekursiven Arbeitsweise kann beispielsweise der String mehrfach in verschiedenen Richtungen durchlaufen werden. Dabei werden die Zeichen in x bzw. y klassifiziert, teilweise sortiert und in einem späteren Schritt auf Basis anderer Teilergebnisse weitersortiert. Die Algorithmen dieser Klasse sind sehr divers. Fast alle haben jedoch gemeinsam, dass sie trotz einer häufig schlechten Worst Case-Laufzeit von in der Praxis meist schneller als rekursive Algorithmen sind. Auch benötigen sie im Allgemeinen deutlich weniger Speicherplatz als andere Algorithmen.[1] Der derzeit schnellste Algorithmus dieser Klasse ist der Suffix-Array-Induced-Sorting-Algorithmus (kurz SAIS) von Nong, Zhang und Chan[4]. Er benötigt lediglich eine Laufzeit in . Der SAIS-Algorithmus erweist sich auch in der Praxis als sehr schnell, wenn bei der Implementierung verschiedene Effekte wie z. B. Cache-Misses berücksichtigt werden.[5] AnwendungenNach der Konstruktion kann das Suffixarray als Index des Texts verwendet werden, um nachfolgende Operationen effizient durchzuführen. Zu diesen Operationen zählen unter anderem Suchanfragen und Kompressionsverfahren. Exakte Suchanfragen (String Matching)Eine exakte Suchanfrage besteht aus einem Suchmuster , das in einem Text gesucht werden soll. Eine Textstelle zählt nur dann als exaktes Vorkommen von , wenn jedes Zeichen der Textstelle mit übereinstimmt. Damit unterscheiden sich diese Anfragen von den nicht exakten Anfragen, bei denen eine festgelegte Anzahl an abweichenden Zeichen erlaubt ist. Es wird bei den exakten Suchanfragen zwischen Entscheidungsanfragen ("Kommt in vor?"), Anzahlanfragen ("Wie oft kommt in vor?") und Aufzählungsanfragen ("An welchen Stellen kommt in vor?") unterschieden, wobei Entscheidungsanfragen ggf. mithilfe von Anzahlanfragen und Anzahlanfragen mit Aufzählungsanfragen beantwortet werden können[6]. Um die Anzahl der exakten Vorkommen von zu bestimmen, müssen im Suffixarray zu alle Suffixe gesucht werden, die mit beginnen. Da das Suffixarray sortiert ist, liegen diese Suffixe alle direkt hintereinander und bilden einen Block. Daher reicht es aus, den lexikographisch kleinsten und den lexikographisch größten Suffix zu bestimmen, die mit beginnen. Mithilfe der binären Suche können diese jeweils in gefunden werden, wobei im Folgenden für die Länge von und für die Länge von steht. Die Anzahl der Vorkommen von ist dann gleich der Anzahl der Suffixe, die in diesem Block liegen. Damit kann die Anzahl der Vorkommen insgesamt in bestimmt werden. Wenn zusätzlich die Ausgabe der Anfangspositionen aller exakten Vorkommen gefordert ist, müssen stattdessen die Werte des Suffixarrays in dem Block zurückgegeben werden. Die Laufzeit hierfür beträgt , wobei für die Anzahl der Vorkommen von in steht[7]. Verfeinerte Verfahren können unter Zuhilfenahme von weiteren Datenstrukturen bessere Laufzeiten erzielen. Wenn das sogenannte LCP-Array (englisch longest common prefix) zu bestimmt und eine geeignete RMQ-Datenstruktur (englisch range minimum query) zu dem LCP-Array konstruiert wurde, können Entscheidungs- sowie Anzahlanfragen in und Aufzählungsanfragen in beantwortet werden[8]. Konstruktion eines SuffixbaumsDas Suffixarray eines Texts wird häufig als Zwischenschritt benutzt, um den zugehörigen Suffixbaum in Linearzeit zu konstruieren[9]. Der Suffixbaum kann anschließend ebenfalls als Index genutzt werden, um Suchanfragen zu beantworten. KompressionVerschiedene Kompressionsverfahren können unter Einsatz des Suffixarrays effizient umgesetzt werden. So kann die Faktorisierung der LZ77-Komprimierung in Linearzeit implementiert werden[10]. Darüber hinaus kann man aus einem bestehenden Suffixarray mit sehr geringem Aufwand die Burrows-Wheeler-Transformation des Textes errechnen. Dazu wird nacheinander für jedes Suffix des Suffixarrays das Zeichen bestimmt, das im Text genau eine Position vor dem Suffix steht, und in einem Array abgelegt[11]. Das resultierende Array ist dann identisch zur Burrows-Wheeler-Transformation des Textes und kann beispielsweise für das bzip2-Kompressionsverfahren verwendet werden. GeschichteSuffixarrays wurden ursprünglich 1990 von Gene Myers und Udi Manber entwickelt, um den Speicherverbrauch im Vergleich zu Suffixbäumen zu reduzieren[2]. Nachdem einige Jahre keine signifikanten Erkenntnisse auftraten, sind Suffixarrays seit ca. 2000 ein beliebtes Forschungsthema. Seitdem wurde eine Vielzahl von Konstruktionsalgorithmen entwickelt, die zahlreiche wünschenswerte Eigenschaften aufweisen. Seit 1999 existieren Algorithmen, die in den meisten Anwendungsfällen schneller als die existierenden Linearzeitalgorithmen sind, schlimmstenfalls jedoch einen Zeitbedarf im Bereich bis haben[3][12]. Die ersten garantierten Linearzeit-Algorithmen (d. h. solche mit Worst Case-Laufzeit ) sind erst seit 2003 bekannt[13][14]. Seit 2004 ist bekannt, dass Suffixarrays jedes Problem mit der gleichen Zeitkomplexität wie Suffixbäume lösen können[15]. Spätestens seit diesem Zeitpunkt sind Suffixarrays daher für fast alle Suffix- und Stringsortierungsaufgaben das Mittel der Wahl. Ab 2005 wurde neben der Konstruktion auch die effiziente Speicherung von Suffixarrays betrachtet. Neben reinen Suffixarrays können nun auch komprimierte Suffixarrays effizient konstruiert und verwendet werden[16][17]. Auch für auf der Burrows-Wheeler-Transformation basierende komprimierte Volltext-Indizes sind sie nützlich. Literatur
WeblinksCommons: Suffix array – Sammlung von Bildern, Videos und Audiodateien
Einzelnachweise
|
Portal di Ensiklopedia Dunia