web-dev-qa-db-fra.com

Un algorithme de compression efficace pour les chaînes de texte courtes

Je cherche un algorithme pour compresser de petites chaînes de texte: 50-1000 octets (c'est-à-dire des URL). Quel algorithme fonctionne le mieux pour cela?

115
Vasily Korolev

Départ Smaz :

Smaz est une bibliothèque de compression simple adaptée à la compression de chaînes très courtes.

57
stvchu

Huffman a un coût statique, la table de Huffman, donc je ne suis pas d'accord, c'est un bon choix.

Il existe des versions adaptatives qui suppriment cela, mais le taux de compression peut en souffrir. En fait, la question que vous devriez vous poser est "quel algorithme pour compresser des chaînes de texte avec ces caractéristiques". Par exemple, si de longues répétitions sont attendues, un simple codage Run-Lengh pourrait suffire. Si vous pouvez garantir que seuls les mots anglais, les espaces, la ponctuation et les chiffres occasionnels seront présents, alors Huffman avec une table de Huffman prédéfinie peut donner de bons résultats.

En règle générale, les algorithmes de la famille Lempel-Ziv ont une compression et des performances très bonnes, et les bibliothèques pour eux abondent. J'irais avec ça.

Avec l'information que ce qui est compressé sont des URL, alors je vous suggère de les CODIFIER avant de compresser (quel que soit l'algorithme facilement disponible). Les URL suivent des modèles bien définis, et certaines parties sont hautement prévisibles. En utilisant ces connaissances, vous pouvez commencer par codifier les URL en un format plus petit, et les idées derrière le codage de Huffman peuvent vous aider.

Par exemple, en traduisant l’URL en un flux binaire, vous pouvez remplacer "http" par le bit 1 et le reste, par le bit "0" suivi du procotol réel (ou utiliser un tableau pour obtenir d’autres protocoles courants, tels que https, ftp, fichier). Le ": //" peut être complètement supprimé, tant que vous pouvez marquer la fin du protocole. Etc. Allez sur le format des URL et réfléchissez à la façon dont elles peuvent être codifiées pour prendre moins d’espace.

28
Daniel C. Sobral

Je n'ai pas le code sous la main, mais j'ai toujours aimé l'approche consistant à créer une table de correspondance 2D de taille 256 * 256 caractères ( RFC 1978 , Compression de prédicteur PPP Protocole ). Pour compresser une chaîne, vous passez en boucle sur chaque caractère et utilisez la table de recherche pour obtenir le prochain caractère "prédit" en utilisant les caractères actuel et précédent comme index dans la table. S'il y a une correspondance, vous écrivez un seul bit 1, sinon écrivez un 0, le caractère et mettez à jour la table de recherche avec le caractère actuel. Cette approche maintient essentiellement une table de recherche dynamique (et brute) du prochain caractère le plus probable du flux de données.

Vous pouvez commencer avec une table de recherche mise à zéro, mais il est évident que cela fonctionne mieux sur des chaînes très courtes s'il est initialisé avec le caractère le plus probable pour chaque paire de caractères, par exemple, pour la langue anglaise. Tant que la table de correspondance initiale est la même pour la compression et la décompression, vous n'avez pas besoin de l'émettre dans les données compressées.

Cet algorithme ne donne pas un taux de compression brillant, mais il est incroyablement économe en ressources de mémoire et de ressources processeur. Il peut également fonctionner sur un flux continu de données. Le décompresseur conserve sa propre copie de la table de consultation lors de la décompression. s'adapte au type de données en cours de compression.

22
redcalx

Tout algorithme/bibliothèque prenant en charge un dictionnaire prédéfini, par ex. zlib .

De cette façon, vous pouvez amorcer le compresseur avec le même type de texte susceptible d'apparaître dans l'entrée. Si les fichiers sont similaires (par exemple, toutes les URL, tous les programmes C, tous les messages StackOverflow, tous les dessins au format ASCII), certaines sous-chaînes apparaîtront dans la plupart des fichiers d’entrée.

Chaque algorithme de compression économisera de l’espace si la même sous-chaîne est répétée plusieurs fois dans un fichier d’entrée (par exemple, "the" en texte anglais ou "int" en code C.)

Mais dans le cas des URL, certaines chaînes (par exemple, " http: // www .", ".Com", ".html", ".aspx" apparaissent généralement une fois dans chaque fichier d'entrée. vous devez les partager entre les fichiers d'une manière ou d'une autre, plutôt que d'avoir une occurrence compressée par fichier, ce qui vous permettra de les placer dans un dictionnaire prédéfini.

11
finnw

Si vous parlez de compresser réellement le texte, pas seulement de le raccourcir, utilisez Deflate/gzip (encapsuleur autour de gzip), le traitement Zip fonctionne bien pour les fichiers et le texte plus petits. D'autres algorithmes sont très efficaces pour les fichiers plus volumineux tels que bzip2, etc.

Wikipedia a une liste de temps de compression. (chercher une comparaison d'efficacité)

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
5
Ryan Christensen

codage de Huffman fonctionne généralement bien pour cela.

3
Zifre

Vous voudrez peut-être jeter un oeil à Schéma de compression standard pour Unicode .

SQL Server 2008 R2 l'utilise en interne et peut atteindre jusqu'à 50% de compression.

2
Le Hibou