Ich lese den Artikel NJ Larsson, A. Moffat: Offline Dictionary-Based Compression , der einen Komprimierungsalgorithmus beschreibt, der, wenn ich ihn richtig verstehe, der Bytepaar-Codierung ziemlich ähnlich ist .
Bei einer Zeichenfolge der Länge versuche ich zu verstehen, wie man sie mit dieser Komprimierungsmethode in linearer Zeit ( komprimieren kann. Wie genau wird das gemacht? Ich habe die Zeitung gelesen, aber ich verstehe immer noch nicht, wie sie eine lineare Zeit erreichen. Vielleicht würde ich sie auf eine andere Weise erklären.n O ( n )
Meine erste Verwirrung entsteht im ersten Schritt des Algorithmus, wo wir das häufigste Paar finden, z. B. wenn abcababcabc
das häufigste Paar ab
beispielsweise durch ein neues Symbol ersetzt wird XcXXcXc
. Ich verstehe nicht, wie wir das häufigste Paar schnell genug finden können. Mein naiver Ansatz wäre, zuerst das erste Paar zu betrachten ab
und dann die Anzahl der Vorkommen zu zählen, dann das nächste Paar zu betrachten bc
und die Anzahl der Vorkommen usw. zu zählen. Dies würde jedoch bereits nur für geben einmal das häufigste Paar finden .
Als nächstes, selbst wenn ich verstanden habe, wie man das häufigste Paar in Zeit findet. Mein nächstes Problem ist, dass wir nicht das häufigste Paar bis zu mal finden müssen? Und daher würde dies eine Gesamtzeit von ?O ( n ) O ( n 2 )
Antworten:
Ich habe den Code überprüft, das Papier erneut gelesen und es scheint, dass der Algorithmus in nicht so funktioniert, wie Sie es beschrieben haben. Die rekursiven Aufrufe zum Finden von Paaren funktionieren inO(n)
O(nlogn) geteilt durch konstant, wenn Sie es bis zum Ende packen möchten. Tatsächlich behält die darunter liegende Struktur Zeiger auf das erste Auftreten von Paaren bei, teilt die Warteschlange von Paaren nach Vorkommen auf, um sie effizient, aber dennoch loglinear zu machen. Auf der anderen Seite durch Analyse des von Ph.D. Schüler des Autors Ich habe mehrere Tricks entdeckt - die Länge der Paare (der ursprüngliche Name) wird als Parameter angegeben (Standard ist 2) und die Wiederholung wird durch Parameter begrenzt, die weitere Aufrufe verwerfen können (Standard ist ungefähr 5 Ebenen), mit Fähigkeit, nur einen Durchgang zu machen oder bis zum Ende zu schieben. Der Standardcode wird in , führt jedoch nicht zu einer optimalen Komprimierung. Es gibt auch Schalter, um Speicher, Zeit oder Neutralität zu bevorzugen.O(n)
Das Papier und der Code zeigen die Verwendung der Hash-Tabelle, die nur in der erwarteten konstanten Zeit ausgeführt wird, aber die angegebene Funktion funktioniert sehr gut mit Zeichen. Außerdem begrenzt der Code die Eingabelänge durch konstante Hardcodierung.
Das Ändern der Hashtabelle in einen Suffixbaum und das Umschreiben des Teils der Wiederholung in Teilpaare der Buchhaltung kann zu besseren Ergebnissen führen. Ich bin mir nicht sicher, ob dies möglich ist, um zu erstellen. Dies wäre wahrscheinlich eine andere Frage.O(n)
Es wird auch ein Trick verwendet, um das Durchlaufen des leeren Raums zu verhindern - der Beginn eines leeren Blocks zeigt auf das erste nicht leere Zeichen, dies beschleunigt jedoch nur das Durchlaufen, immer noch mit loglinearer Zeit. Der Teil, der für dieses Verhalten verantwortlich ist, ersetzt Paare bei jeder Iteration durch das neue Zeichen. Es wäre schneller, nur die Regeln für das Umschreiben beizubehalten und sie zu bearbeiten. Der Zugriff auf die Überprüfung, ob neue Paare eingeführt wurden, würde jedoch erfordern, die Regeln für das Umschreiben mit den neuen Regeln zu vergleichen. In dem Fall erstellen wir einen vollständigen Binärbaum mit Paaren an den Blättern, so dass wir nach dem Ersetzen des Paares durch ein neues Zeichen und der Abstimmung mit dem Elternteil neue Paare an den Blättern bis zur Wurzel erhalten - es gibt Chatacters, dann Paare, dann ,n nn2 nn4 nn8 , ... sehen Sie das Muster, gibt es Paare, sondern nach Algorithmusbeschreibung Diese yelds Zeitnahme nur Eingangsdurchläufe. 2nO(nlogn+n)n16 2n O(nlogn+n)
quelle