Um algoritmo de compactação eficiente para seqüências de texto curtas [fechado]

126

Estou procurando um algoritmo para compactar pequenas seqüências de texto: 50-1000 bytes (ou seja, URLs). Qual algoritmo funciona melhor para isso?

Vasily Korolev
fonte
1
Onde você deseja usar essas strings compactadas?
Gumbo
1
Isso está acontecendo tinyurlsou algo a ver com espaço de armazenamento?
nik
6
Estou interessado em um algoritmo para compactar URLs, a melhor taxa de compactação é mais importante do que o custo de execução. Não estou interessado em serviços online como tinyurls ou tr.im. Estou procurando um algoritmo, não um serviço. Não pense qualquer outra informação poderia ser útil ...
Vasily Korolev
3
@ Gumbo: "Algoritmos de compressão de texto para strings curtas" são suficientes para encontrar algos, por que você está tão interessado em saber para que servem? Tenho certeza de que o OP será capaz de encontrar o que faz o que ele quer.
Dervin Thunk
7
@ Geralmente, uma pequena dica: sempre que você faz uma pergunta sobre SO na forma de "Qual é o melhor XYZ?", Sua pergunta quase recebe votos para fechar, porque pedir o melhor pode levar a produtos desnecessários comparações, ou, na pior das hipóteses, até guerras de chamas. (Geralmente, é necessária apenas uma alteração muito pequena para evitar isso: se você fizesse a mesma pergunta como "Por favor, sugira um XYZ.", Você não obteria tantos votos finais, mesmo que seja basicamente a mesma pergunta!)
stakx - não contribuindo mais com

Respostas:

62

Confira o Smaz :

O Smaz é uma biblioteca de compactação simples, adequada para compactar cadeias muito curtas.

stvchu
fonte
17
Veja github.com/antirez/smaz/blob/master/smaz.c - esta é uma variante de codificação, não compactação por si só (pelo menos não totalmente). Ele usa um dicionário estático de palavras e letras.
Roy Tinker
7
Nota: Este é o projeto de antirez. Ele é um dos principais autores da Redis e tem uma reputação muito forte de lançar código de produção de alta qualidade.
precisa saber é o seguinte
7
O algoritmo smaz é otimizado para textos em inglês, portanto, não funciona bem para cadeias aleatórias. Aqui estão algumas amostras ( 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
Também dê uma olhada em uma compressão mais baixa, mas um rápido algoritmo Shoco ed-von-schleck.github.io/shoco
Dickey Singh
Adicione minha biblioteca Unishox à lista github.com/siara-cc/unishox . Ele tem um desempenho melhor que o Smaz e o Shoco e suporta a compactação de strings UTF-8.
15/02
28

Huffman tem um custo estático, a tabela Huffman, então eu discordo que é uma boa escolha.

Existem versões adaptativas que acabam com isso, mas a taxa de compressão pode sofrer. Na verdade, a pergunta que você deve fazer é "qual algoritmo comprimir seqüências de texto com essas características". Por exemplo, se longas repetições são esperadas, a simples codificação Run-Lengh pode ser suficiente. Se você pode garantir que apenas palavras, espaços, pontuação e dígitos ocasionais em inglês estejam presentes, o Huffman com uma tabela Huffman predefinida poderá gerar bons resultados.

Geralmente, os algoritmos da família Lempel-Ziv têm muito boa compactação e desempenho, e as bibliotecas para eles são abundantes. Eu iria com isso.

Com as informações de que o que está sendo compactado são URLs, sugiro que, antes da compactação (com qualquer algoritmo facilmente disponível), você as CODIFIQUE. Os URLs seguem padrões bem definidos e algumas partes são altamente previsíveis. Ao usar esse conhecimento, você pode codificar os URLs em algo menor para começar, e as idéias por trás da codificação Huffman podem ajudá-lo aqui.

Por exemplo, ao traduzir o URL em um fluxo de bits, você pode substituir "http" pelo bit 1 e qualquer outra coisa pelo bit "0" seguido pelo procotol real (ou usar uma tabela para obter outros protocolos comuns, como https, ftp, arquivo). O ": //" pode ser eliminado por completo, desde que você possa marcar o final do protocolo. Etc. Leia sobre o formato da URL e pense em como eles podem ser codificados para ocupar menos espaço.

Daniel C. Sobral
fonte
4
Não se a tabela huffman for a mesma para todos os arquivos, o que faria sentido se os arquivos forem todos semelhantes.
finnw
1
Se você tiver muitos arquivos pequenos e semelhantes, estará fazendo tudo errado. Primeiro, concatene todos eles (como o tar) e depois comprima isso. Você obterá melhor compactação e o problema deixará de ser "50-1000 bytes".
1813 Daniel C. Sobral
8
@ Daniel: depende se você deseja acesso aleatório aos dados compactados. A compactação de todos juntos evita isso na maioria dos sistemas de compactação.
Steve Jessop
22

Não tenho código em mãos, mas sempre gostei da abordagem de criar uma tabela de pesquisa 2D de tamanho 256 * 256 caracteres ( RFC 1978 , PPP Predictor Compression Protocol ). Para compactar uma string, você faz um loop sobre cada caractere e usa a tabela de pesquisa para obter o próximo caractere 'previsto' usando o caractere atual e o anterior como índices na tabela. Se houver uma correspondência, você escreve um único bit 1; caso contrário, escreva um 0, o caractere e atualize a tabela de pesquisa com o caractere atual. Essa abordagem basicamente mantém uma tabela de pesquisa dinâmica (e bruta) do próximo caractere mais provável no fluxo de dados.

Você pode começar com uma tabela de pesquisa zerada, mas obviamente funciona melhor em cadeias muito curtas se for inicializada com o caractere mais provável para cada par de caracteres, por exemplo, para o idioma inglês. Desde que a tabela de pesquisa inicial seja a mesma para compactação e descompactação, você não precisará emiti-la nos dados compactados.

Esse algoritmo não fornece uma taxa de compactação brilhante, mas é incrivelmente econômico com recursos de memória e CPU e também pode trabalhar em um fluxo contínuo de dados - o descompressor mantém sua própria cópia da tabela de pesquisa à medida que descompacta, portanto, a tabela de pesquisa ajusta ao tipo de dados que está sendo compactado.

redcalx
fonte
Mas como o preditor se comportaria com uma sentença normal em inglês? O exemplo dado tem redundância muito forte e o ganho é mínimo.
Danubian Sailor
Uma tabela de pesquisa de 256 * 256 não soa "incrivelmente frugal com memória" ...!
24517 MikeW
@ MikeW Bem, são 65 kilobytes.
redcalx
@redcalx Se tivesse sido 65 bytes eu poderia ter concordado!
27517 MikeW
11

Qualquer algoritmo / biblioteca que suporte um dicionário predefinido, por exemplo, zlib .

Dessa forma, você pode preparar o compressor com o mesmo tipo de texto que provavelmente aparecerá na entrada. Se os arquivos forem semelhantes de alguma forma (por exemplo, todos os URLs, todos os programas C, todas as postagens StackOverflow, todos os desenhos de arte ASCII), determinadas substrings aparecerão na maioria ou em todos os arquivos de entrada.

Todo algoritmo de compactação economizará espaço se a mesma substring for repetida várias vezes em um arquivo de entrada (por exemplo, "the" no texto em inglês ou "int" no código C.)

Porém, no caso de URLs, certas strings (por exemplo, " http: // www .", ".Com", ".html", ".aspx" geralmente aparecem uma vez em cada arquivo de entrada. Portanto, é necessário compartilhá-las entre os arquivos de alguma forma, em vez de ter uma ocorrência compactada por arquivo, colocando-as em um dicionário predefinido, isso é o

finnw
fonte
2
Dicas para usar o dicionário personalizado: stackoverflow.com/questions/2011653
Trenton
4

A codificação de Huffman geralmente funciona bem para isso.

Zifre
fonte
4
Esta não é uma resposta apenas para link; sem o link, ainda é uma resposta válida.
SL Barth - Restabelece Monica
..e ainda não é uma boa resposta. (Não o suficiente informações relevantes trazidos.)
user2864740
4

Se você está realmente pensando em compactar o texto e não apenas encurtar, em seguida, Deflate / gzip (wrapper em torno do gzip), o zip funciona bem para arquivos e texto menores. Outros algoritmos são altamente eficientes para arquivos maiores, como bzip2 etc.

A Wikipedia possui uma lista de tempos de compactação. (procure comparação de eficiência)

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
fonte
6
Ele quer compactar texto e não arquivos.
Gumbo
3
Você pode compactar texto e binários com esses algoritmos. De fato, usamos deflate dentro de um sistema cms que roda em python.
21419 Ryan Christensen #
Um exemplo em C # usando gzip para seqüências de caracteres está aqui: csharphelp.com/archives4/archive689.html
Ryan Christensen
módulo zlib em python para cordas compressão: python.org/doc/2.5.2/lib/module-zlib.html
Ryan Christensen
3
O gzip (e o zlib) usa deflate e adiciona sobrecarga de wrapper / framing. O deflate direto / LZ77 (a sobrecarga do dicionário e a eficiência ainda depende da implementação de tais configurações) podem reduzir a sobrecarga do ponto de equilíbrio. Isso é para seqüências de caracteres "curtas" entre dezenas e centenas de caracteres, é claro (ainda deve haver um pouco para indicar "foi compactado"? Para evitar o aumento de dados). Sobrecarga extra maior não importa. À medida que o texto aumenta. Os números publicados aqui parecem ser para grandes arquivos de texto (muitos segundos para serem executados!), Enquanto o OP solicita 50-1000 charters - muito pequeno em comparação.
precisa saber é o seguinte
2

Você pode dar uma olhada no Esquema de compactação padrão para Unicode .

O SQL Server 2008 R2 usa-o internamente e pode atingir até 50% de compactação.

Le Hibou
fonte
O SCSU 'comprime' Unicode não inglês em codificações UTF-16 / MB. Se baseado em Inglês Unicode / plain-old-ASCII, UTF-8 também 'compressas' 50% do UTF-16 ..
user2864740