Je recherche 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?
tinyurls
ou quelque chose à voir avec l'espace de stockage?
Je recherche 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?
tinyurls
ou quelque chose à voir avec l'espace de stockage?
Réponses:
Découvrez Smaz :
Smaz est une bibliothèque de compression simple adaptée à la compression de chaînes très courtes.
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%
Huffman a un coût statique, la table Huffman, donc je ne suis pas d'accord que ce soit un bon choix.
Il existe des versions adaptatives qui éliminent cela, mais le taux de compression peut en souffrir. En fait, la question que vous devriez vous poser est "quel algorithme pour compresser les chaînes de texte avec ces caractéristiques". Par exemple, si de longues répétitions sont attendues, un simple encodage 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 pourrait donner de bons résultats.
En règle générale, les algorithmes de la famille Lempel-Ziv ont une très bonne compression et de très bonnes performances, et leurs bibliothèques abondent. J'irais avec ça.
Avec l'information que ce qui est compressé sont des URL, alors je suggérerais qu'avant de compresser (avec n'importe quel algorithme facilement disponible), vous les CODIFIEZ. Les URL suivent des modèles bien définis, et certaines parties sont hautement prévisibles. En utilisant ces connaissances, vous pouvez codifier les URL en quelque chose de plus petit pour commencer, et les idées derrière l'encodage Huffman peuvent vous aider ici.
Par exemple, en traduisant l'URL en un flux binaire, vous pouvez remplacer "http" par le bit 1, et tout le reste par le bit "0" suivi du véritable procotol (ou utiliser une table pour obtenir d'autres protocoles courants, comme https, ftp, fichier). Le ": //" peut être complètement supprimé, tant que vous pouvez marquer la fin du protocole. Etc. Allez lire sur le format des URL et réfléchissez à la façon dont ils peuvent être codifiés pour prendre moins de place.
Je n'ai pas de code sous la main, mais j'ai toujours aimé l'approche consistant à créer une table de recherche 2D de taille 256 * 256 caractères ( RFC 1978 , PPP Predictor Compression Protocol ). Pour compresser une chaîne, vous bouclez sur chaque caractère et utilisez la table de recherche pour obtenir le prochain caractère «prédit» en utilisant le caractère actuel et précédent comme index dans la table. S'il y a une correspondance, vous écrivez un seul bit, sinon écrivez un 0, le char et mettez à jour la table de recherche avec le char actuel. Cette approche maintient essentiellement une table de recherche dynamique (et brute) du caractère suivant le plus probable dans le flux de données.
Vous pouvez commencer avec une table de recherche à zéro, mais évidemment, elle fonctionne mieux sur des chaînes très courtes si elle est initialisée avec le caractère le plus probable pour chaque paire de caractères, par exemple pour la langue anglaise. Tant que la table de recherche 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 mémoire et en ressources CPU et peut également fonctionner sur un flux continu de données - le décompresseur conserve sa propre copie de la table de recherche lors de la décompression, donc la table de recherche s'adapte au type de données compressées.
Tout algorithme / bibliothèque prenant en charge un dictionnaire prédéfini, par exemple zlib .
De cette façon, vous pouvez amorcer le compresseur avec le même type de texte qui est susceptible d'apparaître dans l'entrée. Si les fichiers sont similaires d'une manière ou d'une autre (par exemple, toutes les URL, tous les programmes C, toutes les publications StackOverflow, tous les dessins ASCII-art) alors certaines sous-chaînes apparaîtront dans la plupart ou tous les 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" apparaîtront généralement une fois dans chaque fichier d'entrée. Vous devez donc les partager entre les fichiers. plutôt que d'avoir une occurrence compressée par fichier. Les placer dans un dictionnaire prédéfini y parviendra.
Le codage Huffman fonctionne généralement bien pour cela.
Si vous parlez de compresser le texte, pas seulement de raccourcir, puis Deflate / gzip (wrapper autour de gzip), zip fonctionne bien pour les fichiers et le texte plus petits. D'autres algorithmes sont très efficaces pour les fichiers plus volumineux comme bzip2, etc.
Wikipedia a une liste des temps de compression. (cherchez 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
Vous voudrez peut-être jeter un œil au schéma de compression standard pour Unicode .
SQL Server 2008 R2 l'utilise en interne et peut atteindre jusqu'à 50% de compression.