Ein effizienter Komprimierungsalgorithmus für kurze Textzeichenfolgen [geschlossen]

126

Ich suche nach einem Algorithmus zum Komprimieren kleiner Textzeichenfolgen: 50-1000 Bytes (dh URLs). Welcher Algorithmus funktioniert dafür am besten?

Wassili Korolev
quelle
1
Wo möchten Sie diese komprimierten Zeichenfolgen verwenden?
Gumbo
1
Geht das in Richtung tinyurlsoder hat etwas mit Speicherplatz zu tun?
Nik
6
Ich interessiere mich für einen Algorithmus zum Komprimieren von URLs. Das beste Komprimierungsverhältnis ist wichtiger als die laufenden Kosten. Kein Interesse an Online-Diensten wie tinyurls oder tr.im. Ich suche einen Algorithmus, keinen Dienst. Denken Sie nicht, dass andere Informationen nützlich sein könnten ...
Vasily Korolev
3
@Gumbo: "Textkomprimierungsalgorithmen für kurze Zeichenfolgen" reichen aus, um Algen zu finden. Warum sind Sie so daran interessiert zu wissen, wofür sie gedacht sind? Ich bin sicher, dass das OP denjenigen finden wird, der tut, was er will.
Dervin Thunk
7
@Vasily, ein kleiner Hinweis: Jedes Mal , wenn Sie eine Frage auf SO in Form zu fragen : „Was ist das beste ? XYZ“, ist Ihre Frage fast zwangsläufig Stimmen erhalten zu schließen , weil für die besten fragen könnte , um unnötiges Produkt führen Vergleiche oder im schlimmsten Fall sogar Flammenkriege. (Normalerweise ist nur eine sehr kleine Änderung erforderlich, um dies zu vermeiden: Wenn Sie dieselbe Frage wie "Bitte schlagen Sie eine XYZ vor."
Stellen

Antworten:

62

Schauen Sie sich Smaz an :

Smaz ist eine einfache Komprimierungsbibliothek, die zum Komprimieren sehr kurzer Zeichenfolgen geeignet ist.

stvchu
quelle
17
Siehe github.com/antirez/smaz/blob/master/smaz.c - dies ist eine Variante der Codierung, keine Komprimierung an sich (zumindest nicht vollständig). Er verwendet ein statisches Wort- und Buchstabenwörterbuch.
Roy Tinker
7
Hinweis: Dies ist das Projekt von Antirez. Er ist einer der Hauptautoren von Redis und hat den Ruf, qualitativ hochwertigen Produktionscode zu veröffentlichen.
Homer6
7
Der smaz-Algorithmus ist für englische Texte optimiert und funktioniert daher nicht gut für zufällige Zeichenfolgen. Hier einige Beispiele ( string:orig_size:compr_size:space_savings): This is the very end of it.:27:13:52%, Lorem ipsum dolor sit amet:26:19:27%, Llanfairpwllgwyngyll:20:17:15%, aaaaaaaaaaaaa:13:13:0%, 2BTWm6WcK9AqTU:14:20:-43%,XXX:3:5:-67%
mykhal
4
Schauen Sie sich auch eine niedrigere Komprimierung an, aber einen schnellen Algorithmus shoco ed-von-schleck.github.io/shoco
Dickey Singh
Fügen Sie meine Bibliothek Unishox zur Liste github.com/siara-cc/unishox hinzu . Es bietet eine bessere Leistung als Smaz und Shoco und unterstützt das Komprimieren von UTF-8-Zeichenfolgen.
Arun
28

Huffman hat statische Kosten, die Huffman-Tabelle, daher bin ich nicht der Meinung, dass dies eine gute Wahl ist.

Es gibt adaptive Versionen, die dies beseitigen, aber die Komprimierungsrate kann darunter leiden. Die Frage, die Sie sich stellen sollten, lautet: "Welcher Algorithmus zum Komprimieren von Textzeichenfolgen mit diesen Merkmalen". Wenn beispielsweise lange Wiederholungen erwartet werden, kann eine einfache Run-Lengh-Codierung ausreichen. Wenn Sie garantieren können, dass nur englische Wörter, Leerzeichen, Satzzeichen und gelegentliche Ziffern vorhanden sind, kann Huffman mit einer vordefinierten Huffman-Tabelle gute Ergebnisse liefern.

Im Allgemeinen weisen Algorithmen der Lempel-Ziv-Familie eine sehr gute Komprimierung und Leistung auf, und es gibt zahlreiche Bibliotheken für sie. Ich würde damit gehen.

Mit der Information, dass es sich bei den zu komprimierenden URLs um URLs handelt, würde ich vorschlagen, dass Sie sie vor dem Komprimieren (mit jedem leicht verfügbaren Algorithmus) KODIFIZIEREN. URLs folgen genau definierten Mustern, und einige Teile davon sind sehr vorhersehbar. Wenn Sie dieses Wissen nutzen, können Sie die URLs zunächst in etwas Kleineres kodieren, und Ideen hinter der Huffman-Codierung können Ihnen hier helfen.

Wenn Sie beispielsweise die URL in einen Bitstrom übersetzen, können Sie "http" durch das Bit 1 und alles andere durch das Bit "0" gefolgt vom eigentlichen Procotol ersetzen (oder eine Tabelle verwenden, um andere gängige Protokolle wie https zu erhalten). FTP, Datei). Das ": //" kann ganz gelöscht werden, solange Sie das Ende des Protokolls markieren können. Lesen Sie mehr über das URL-Format und überlegen Sie, wie sie codiert werden können, um weniger Speicherplatz zu beanspruchen.

Daniel C. Sobral
quelle
4
Nicht, wenn die Huffman-Tabelle für alle Dateien gleich ist. Dies wäre sinnvoll, wenn alle Dateien einander ähnlich wären.
Finnw
1
Wenn Sie viele, ähnliche, kleine Dateien haben, machen Sie alles falsch. Verketten Sie sie zuerst alle (wie es Teer tut) und komprimieren Sie sie dann. Sie erhalten eine bessere Komprimierung und das Problem hört auf, "50-1000 Bytes" zu sein.
Daniel C. Sobral
8
@ Daniel: hängt davon ab, ob Sie zufälligen Zugriff auf die komprimierten Daten wünschen. Das Komprimieren zusammen verhindert dies bei den meisten Komprimierungssystemen.
Steve Jessop
22

Ich habe nicht den Code zu Hand, aber ich mochte immer die Annäherung eines Tabellennachschlag 2D Aufbau der Größe 256 * 256 Zeichen ( RFC 1978 , PPP Predictor Compression Protocol ). Um eine Zeichenfolge zu komprimieren, durchlaufen Sie jedes Zeichen und verwenden die Nachschlagetabelle, um das 'vorhergesagte' nächste Zeichen zu erhalten, wobei das aktuelle und das vorherige Zeichen als Indizes für die Tabelle verwendet werden. Wenn es eine Übereinstimmung gibt, schreiben Sie ein einzelnes 1-Bit, andernfalls schreiben Sie eine 0, das Zeichen und aktualisieren die Nachschlagetabelle mit dem aktuellen Zeichen. Bei diesem Ansatz wird im Wesentlichen eine dynamische (und grobe) Nachschlagetabelle des wahrscheinlichsten nächsten Zeichens im Datenstrom beibehalten.

Sie können mit einer auf Null gesetzten Nachschlagetabelle beginnen, aber offensichtlich funktioniert sie am besten bei sehr kurzen Zeichenfolgen, wenn sie mit dem wahrscheinlichsten Zeichen für jedes Zeichenpaar initialisiert wird, z. B. für die englische Sprache. Solange die anfängliche Nachschlagetabelle für die Komprimierung und Dekomprimierung identisch ist, müssen Sie sie nicht in die komprimierten Daten ausgeben.

Dieser Algorithmus bietet kein brillantes Komprimierungsverhältnis, ist jedoch unglaublich sparsam mit Speicher- und CPU-Ressourcen und kann auch mit einem kontinuierlichen Datenstrom arbeiten. Der Dekomprimierer verwaltet beim Dekomprimieren eine eigene Kopie der Nachschlagetabelle, also der Nachschlagetabelle passt sich dem Typ der zu komprimierenden Daten an.

Redcalx
quelle
Aber wie würde sich der Prädiktor mit einem normalen englischen Satz verhalten? Das gegebene Beispiel hat eine sehr starke Redundanz und die Verstärkung ist minimal.
Danubian Sailor
Eine 256 * 256-Nachschlagetabelle klingt nicht "unglaublich sparsam mit Speicher" ...!
MikeW
@ MikeW Nun, es sind 65 Kilobyte.
Redcalx
@redcalx Wenn es 65 Bytes gewesen wären, hätte ich vielleicht zugestimmt!
MikeW
11

Jeder Algorithmus / jede Bibliothek, die ein voreingestelltes Wörterbuch unterstützt, z . B. zlib .

Auf diese Weise können Sie den Kompressor mit demselben Text grundieren, der wahrscheinlich in der Eingabe erscheint. Wenn die Dateien in irgendeiner Weise ähnlich sind (z. B. alle URLs, alle C-Programme, alle StackOverflow-Beiträge, alle ASCII-Zeichnungen), werden bestimmte Teilzeichenfolgen in den meisten oder allen Eingabedateien angezeigt.

Jeder Komprimierungsalgorithmus spart Platz, wenn derselbe Teilstring in einer Eingabedatei mehrmals wiederholt wird (z. B. "the" im englischen Text oder "int" im C-Code).

Bei URLs werden bestimmte Zeichenfolgen (z. B. " http: // www .", ".Com", ".html", ".aspx" normalerweise einmal in jeder Eingabedatei angezeigt. Sie müssen sie also zwischen Dateien freigeben Anstatt ein komprimiertes Vorkommen pro Datei zu haben, wird dies durch Platzieren in einem voreingestellten Wörterbuch erreicht.

finnw
quelle
2
Tipps zur Verwendung des benutzerdefinierten Wörterbuchs: stackoverflow.com/questions/2011653
Trenton
4

Die Huffman-Codierung funktioniert hierfür im Allgemeinen in Ordnung.

Zifre
quelle
4
Dies ist keine reine Linkantwort. Ohne den Link ist es immer noch eine gültige Antwort.
SL Barth - Stellen Sie Monica am
..und immer noch keine gute Antwort. (Nicht genügend relevante Informationen eingebracht.)
user2864740
4

Wenn Sie davon sprechen, den Text tatsächlich zu komprimieren und nicht nur zu kürzen, sondern Deflate / gzip (Wrapper um gzip), eignet sich zip gut für kleinere Dateien und Text. Andere Algorithmen sind für größere Dateien wie bzip2 usw. hocheffizient.

Wikipedia hat eine Liste der Komprimierungszeiten. (Vergleich der Effizienz)

Name       | Text         | Binaries      | Raw images
-----------+--------------+---------------+-------------
7-zip      | 19% in 18.8s | 27% in  59.6s | 50% in 36.4s
bzip2      | 20% in  4.7s | 37% in  32.8s | 51% in 20.0s
rar (2.01) | 23% in 30.0s | 36% in 275.4s | 58% in 52.7s
advzip     | 24% in 21.1s | 37% in  70.6s | 57& in 41.6s
gzip       | 25% in  4.2s | 39% in  23.1s | 60% in  5.4s
zip        | 25% in  4.3s | 39% in  23.3s | 60% in  5.7s
Ryan Christensen
quelle
6
Er möchte Text und keine Dateien komprimieren.
Gumbo
3
Mit diesen Algorithmen können Sie Text und Binärdateien komprimieren. Tatsächlich verwenden wir Deflate in einem CMS-System, das in Python ausgeführt wird.
Ryan Christensen
Ein Beispiel in C # mit gzip für Zeichenfolgen ist hier: csharphelp.com/archives4/archive689.html
Ryan Christensen
zlib-Modul in Python zum Komprimieren von Zeichenfolgen: python.org/doc/2.5.2/lib/module-zlib.html
Ryan Christensen
3
gzip (und zlib) verwendet deflate und fügt Wrapper- / Framing-Overhead hinzu. Direct deflate / LZ77 (Wörterbuch-Overhead und Effizienz hängen immer noch von der Implementierung solcher und Einstellungen ab) kann den Break-Even-Overhead reduzieren. Dies gilt natürlich für "kurze" Zeichenfolgen mit Dutzenden bis Hunderten von Zeichen (sollte immer noch ein bisschen anzeigen, ob dies komprimiert wurde, um eine Vergrößerung der Daten zu vermeiden). Ein größerer zusätzlicher Aufwand spielt keine Rolle. Wenn der Text zunimmt. Die hier angegebenen Zahlen scheinen für große Textdateien zu gelten (viele Sekunden bis zur Ausführung!), Während OP nach 50-1000 Chartern fragt - im Vergleich sehr klein .
user2864740
2

Vielleicht möchten Sie sich das Standardkomprimierungsschema für Unicode ansehen .

SQL Server 2008 R2 verwendet es intern und kann eine Komprimierung von bis zu 50% erreichen.

Le Hibou
quelle
SCSU 'komprimiert' nicht-englischen Unicode in UTF-16 / MB-Codierungen. Wenn Unicode / Plain-Old-ASCII auf Englisch basiert, "komprimiert" UTF-8 auch 50% von UTF-16 ..
user2864740