2012-06-04 12 views
5

Quiero comprimir cadenas muy pequeñas (aproximadamente 75-100 longitud C# cadena). En el momento en que se crea el diccionario, ya conozco todas las cadenas cortas (casi un billón). No habrá cadenas cortas adicionales en el futuro. Necesito extra exactamente una cadena sin descomprimir otras cadenas.Comprimir cadenas pequeñas, ¿con qué crear diccionario externo?

Ahora estoy buscando para una biblioteca o la mejor manera de hacer lo siguiente:

  1. crear un diccionario utilizando todas las cadenas que tengo
  2. usar el diccionario para comprimir cada cadena
  3. una manera de comprimir una cadena usando el diccionario de 1.

Encontré un good related question, pero esto no es específico de C#. Tal vez hay algo para C# No lo sé, o una biblioteca de lujo o alguien ya lo ha hecho. Esa es la razón por la que hago esta pregunta.

EDIT:

con el diccionario Estoy hablando de cosas como esta: http://en.wikipedia.org/wiki/Dictionary_coder Pero todo ayuda a conseguir las cadenas más cortas. Las cadenas son mensajes de texto cortos en varios idiomas y URL (30%/70%). No es necesario que las cadenas comprimidas sean legibles por humanos. Se almacenará en archivos binarios.

+0

¿Qué tipo de datos hay en las cadenas? (¿en su mayoría ASCII? ¿Cartas aleatorias? ¿GUID?) – Cameron

+0

Por diccionario, ¿te refieres a la clase .NET 'Dictionary' que almacena pares clave-valor? ¿Las cadenas se usarán como claves o valores en su diccionario? Si las cadenas son solo valores, ¿cuáles serán las claves? –

+0

principalmente ascii, no al azar. Como mensajes cortos de texto, oraciones y urls. – Chris

Respuesta

1

Si hay un billón de cadenas y no más, entonces cada una se puede representar en 40 bits (5 bytes). Todo lo que necesita es una forma de utilizar los 5 bytes como un índice para el billón de cadenas.

¿Cómo se conocen todos los trillones de cuerdas? Si el compresor y el descompresor tienen acceso a todos los trillones de cadenas, o si hay forma de ordenar y recrear las cadenas, entonces todo lo que necesita es el índice.

Si no puede encontrar una manera de indexar las cadenas, puede tomar un subconjunto de las cadenas y usarlas como diccionario para un compresor.Simplemente tome la muestra más representativa (necesita averiguar qué podría hacer que algunas de las cadenas sean más comunes que las otras cadenas o más representativas de las otras cadenas) y concatenarlas en un diccionario de 32K. Alrededor de 400 de tus billones de cuerdas. Luego zlib deflateSetDictionary en el extremo de la compresión e inflateSetDictionary en el extremo de la descompresión, ambos usando exactamente el mismo diccionario de 32K. Eso proporcionará una buena compresión en las cuerdas cortas.

+0

La primera no es aplicable en un dominio especial. Pero el segundo (deflateSetDictionary) parece muy prometedor. Tengo una pregunta sobre los diccionarios: digamos que tengo en mi diccionario los siguientes valores: "CDEFGHIJK" y "ABC" y otros. Cuando comprime la cadena "ABCDEFGHIJK", ¿usará el valor "ABC" y luego no "CDEFGHIJK" de mi diccionario, o no usará "ABC" pero usará "CDEFGHIJK" (¿qué sería mejor?) – Chris

+0

Una pregunta adicional: Usted escribió que debería usar 400 de mis billones de cuerdas. ¿Tiene 32K el tamaño del diccionario o el recuento de valores? Como parece que es una matriz de bytes, anulará las cadenas terminadas, teniendo la cadena más probable al final. – Chris

+0

deflate encontrará y usará la cadena más larga para unir. Eso es generalmente mejor. Si sabe qué cadenas pueden ser más comunes, debe ponerlas al final del diccionario, y las menos comunes al inicio. (Esto da como resultado menos bits en promedio para la codificación de las distancias). 32K es el tamaño del diccionario. Así que 400 cuerdas es solo una estimación aproximada de su "75-100" en cuanto a cuántos encajarán. –

1

no he usado, pero Smaz suena prometedor para este ...

Smaz es una biblioteca de compresión simple adecuada para la compresión muy cadenas cortas. Las bibliotecas de compresión de uso general construirán el estado necesario para comprimir datos dinámicamente, para poder comprimir todo tipo de datos. Esta es una muy buena idea, pero no para un problema específico de : la compresión de cadenas pequeñas no funcionará.

Smaz lugar no es bueno para la compresión de datos de propósito general, pero puede comprimir texto en un 40-50% en el caso promedio (funciona mejor con Inglés), y es capaz de realizar un poco de compresión para HTML y urls también. ¡El punto importante es que Smaz puede comprimir incluso cadenas de dos o tres bytes!

Por ejemplo, la cadena "the" está comprimida en un solo byte.

Dado que está escrito en C, echa un vistazo a Bart De Smet's example for interoping with C through C#.

+0

Si son cadenas de texto cortas de un idioma conocido; smaz suena ideal; comprimirá verbos cortos comunes (el, eso, él, ella, yo, etc.) en secuencias de bytes muy cortas. Si las cuerdas pierden ese patrón, ¡incluso puede terminar viendo que sus cadenas comprimidas son más largas! –

+0

Puede intentar traducirlo o usar interoperabilidad (ver mi respuesta actualizada). –

+0

Versión de C# aquí: https://github.com/poulfoged/SentenceCompression – gameweld

Cuestiones relacionadas