Sto cercando un algoritmo per comprimere stringhe di testo di piccole dimensioni: 50-1000 byte (ovvero URL). Quale algoritmo funziona meglio per questo?
tinyurls
o qualcosa a che fare con lo spazio di archiviazione?
Sto cercando un algoritmo per comprimere stringhe di testo di piccole dimensioni: 50-1000 byte (ovvero URL). Quale algoritmo funziona meglio per questo?
tinyurls
o qualcosa a che fare con lo spazio di archiviazione?
Risposte:
Smaz è una semplice libreria di compressione adatta per comprimere stringhe molto brevi.
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 ha un costo statico, il tavolo Huffman, quindi non sono d'accordo che sia una buona scelta.
Esistono versioni adattative che eliminano ciò, ma il tasso di compressione potrebbe risentirne. In realtà, la domanda che dovresti porre è "quale algoritmo per comprimere le stringhe di testo con queste caratteristiche". Ad esempio, se sono previste lunghe ripetizioni, la semplice codifica Run-Lengh potrebbe essere sufficiente. Se puoi garantire che saranno presenti solo parole inglesi, spazi, punteggiatura e cifre occasionali, allora Huffman con una tabella Huffman predefinita potrebbe produrre buoni risultati.
Generalmente, gli algoritmi della famiglia Lempel-Ziv hanno una compressione e prestazioni molto buone e abbondano le loro librerie. Vorrei andare con quello.
Con l'informazione che ciò che viene compresso sono URL, allora suggerirei che, prima di comprimerlo (con qualunque algoritmo sia facilmente disponibile), li CODIFICI. Gli URL seguono schemi ben definiti e alcune parti sono altamente prevedibili. Facendo uso di questa conoscenza, è possibile codificare gli URL in qualcosa di più piccolo per cominciare, e le idee alla base della codifica Huffman possono aiutarti qui.
Ad esempio, traducendo l'URL in un flusso di bit, è possibile sostituire "http" con il bit 1 e qualsiasi altra cosa con il bit "0" seguito dall'attuale procotol (o utilizzare una tabella per ottenere altri protocolli comuni, come https, ftp, file). ": //" può essere eliminato del tutto, purché sia possibile contrassegnare la fine del protocollo. Ecc. Leggi il formato URL e pensa a come possono essere codificati per occupare meno spazio.
Non ho un codice a portata di mano, ma mi è sempre piaciuto l'approccio alla costruzione di una tabella di ricerca 2D di dimensioni 256 * 256 caratteri ( RFC 1978 , protocollo di compressione Predictor PPP ). Per comprimere una stringa esegui il ciclo su ciascun carattere e utilizza la tabella di ricerca per ottenere il carattere successivo "previsto" utilizzando il carattere corrente e precedente come indici nella tabella. Se c'è una corrispondenza, scrivi un singolo 1 bit, altrimenti scrivi uno 0, il carattere e aggiorna la tabella di ricerca con il carattere corrente. Questo approccio mantiene sostanzialmente una tabella di ricerca dinamica (e grezza) del prossimo personaggio più probabile nel flusso di dati.
Puoi iniziare con una tabella di ricerca azzerata, ma ovviamente funziona meglio su stringhe molto brevi se viene inizializzato con il carattere più probabile per ciascuna coppia di caratteri, ad esempio per la lingua inglese. Finché la tabella di ricerca iniziale è la stessa per la compressione e la decompressione non è necessario emetterla nei dati compressi.
Questo algoritmo non offre un brillante rapporto di compressione, ma è incredibilmente semplice con risorse di memoria e CPU e può anche lavorare su un flusso continuo di dati: il decompressore mantiene la propria copia della tabella di ricerca mentre si decomprime, quindi la tabella di ricerca si adatta al tipo di dati compressi.
Qualsiasi algoritmo / libreria che supporti un dizionario predefinito, ad esempio zlib .
In questo modo è possibile adescare il compressore con lo stesso tipo di testo che è probabile che appaia nell'input. Se i file sono simili in qualche modo (ad es. Tutti gli URL, tutti i programmi C, tutti i post StackOverflow, tutti i disegni di arte ASCII), alcune sottostringhe appariranno nella maggior parte o in tutti i file di input.
Ogni algoritmo di compressione consente di risparmiare spazio se la stessa sottostringa viene ripetuta più volte in un file di input (ad es. "The" in inglese o "int" in codice C.)
Ma nel caso di URL determinate stringhe (ad es. " Http: // www .", ".Com", ".html", ".aspx" appariranno in genere una volta in ciascun file di input. Quindi è necessario condividerle tra i file in qualche modo piuttosto che avere un'occorrenza compressa per file. Posizionandoli in un dizionario preimpostato si otterrà questo.
La codifica di Huffman generalmente funziona bene per questo.
Se stai parlando di comprimere effettivamente il testo non solo di accorciare, quindi Deflate / gzip (wrapper attorno a gzip), zip funziona bene per file e testo più piccoli. Altri algoritmi sono altamente efficienti per file più grandi come bzip2 ecc.
Wikipedia ha un elenco di tempi di compressione. (cerca il confronto di efficienza)
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
Potresti dare un'occhiata allo schema di compressione standard per Unicode .
SQL Server 2008 R2 lo utilizza internamente e può ottenere una compressione fino al 50%.