2010-12-03 19 views
6

Digamos que tengo muchos objetos que contienen cadenas de longitud no trivial (alrededor de ~ 3-4kb). Las cadenas son todas diferentes entre sí, pero al mismo tiempo contienen muchas partes/subsecuencias comunes. En promedio, quizás el 80-90% de una cuerda individual está contenida con las otras también. ¿Existe una manera fácil de explotar automáticamente esta gran redundancia para comprimir los datos?
Idealmente, la solución sería C++ y transparente para el usuario (es decir, puedo usarla como si estuviera accediendo a un estándar de lectura solo const std :: string pero en lugar de leer desde el almacenamiento comprimido).almacenamiento de cadena comprimida

+0

¿Cómo las cadenas llegan a tener subsecuencias comunes? ¿Esto se debe a ediciones repetidas o coincidencia de los datos? – SingleNegationElimination

+0

Imagine HTML estático sin soporte para CSS. Tiene muchos html redundantes y solo unas pocas partes cambiantes que contienen la información real. – BuschnicK

+0

1 GB de ram se mantendrá en el orden de 100.000 blobs sin comprimir con un tamaño de 3-4 KB. ¿Realmente lo necesitas para que quepa en menos? – SingleNegationElimination

Respuesta

3

Algorítmicamente, Lempel–Ziv–Welch con un diccionario para todos los objetos/cadenas podría ser un buen comienzo.

+0

Si se crean dinámicamente muchas cadenas a lo largo del tiempo, este diccionario crecerá en grande. Así que, al final, puede ser una idea más simple y mejor que solo LZW comprima las cadenas por separado. –

+0

Se crearán muy pocas cadenas una vez que se haya cargado el lote inicial, por lo que no esperaría un problema allí ... – BuschnicK

2

Si las partes comunes de las cadenas son comunes porque están compuestas de otras cadenas, entonces puede obtener algo de tracción usando la clase stlportrope, que se ve por todo el mundo como std :: string, pero utiliza subcadena representación en árbol con copiar al escribir que los dos muy eficiente del espacio (subcadenas comunes son compartidos) y muy bueno en las inserciones y eliminaciones (log (n)) hace

al usar la cuerda:

  • usted está haciendo un motor de plantilla. las instancias de documentos se crean a partir de una plantilla sustituyendo datos variables en la plantilla y luego se almacenan en caché para usos futuros. Las partes que son comunes a las plantillas y las instancias se almacenan solo una vez y se comparten entre instancias, insertos y eliminaciones son baratas.

Cuando no utilizar la cuerda:

  • que está cargando muchos documentos desde fuera del dominio de la aplicación (desde el disco, o en una red) y su utilización sin modificaciones. la cuerda no comparte cuerdas si no se copian de una cuerda a otra. Si puede permitirse hacer el trabajo para encontrar las subcadenas comunes, la cuerda todavía se puede usar para mejorar sus representaciones finales.
+0

Creo que tiene más que copiar en escritura. Creo que los datos se almacenan en un árbol de cadenas, no en una zona de memoria contigua. –

+0

Es copy-on-write combinado con la capacidad de anteponer a cadenas con el mismo costo algorítmico que se agrega a ellos. –

+0

Creo que encajo su segundo caso: mis cadenas no están controladas por mí y las obtengo de una base de datos. – BuschnicK

3

Puede usar huffman coding la implementación no es difícil, también hay algoritmos de zip en idiomas (como C# y java) y puede usarlos.

También Si está seguro de que el 80-90% se repite en todos, cree un diccionario de todas las palabras, luego, para cada cadena, la posición de la palabra del diccionario, significa que tiene una matriz de bits de gran tamaño (10000 ie) y marque posición relacionada bits[i] a 1 si existe un words[i] en la cadena actual. piense que cada longitud de palabra es de 5 caracteres, entonces la abreviatura toma alrededor de 1/5 de tamaño.

1

Como mencionó @Saeed, una codificación Huffman simple funcionará bien aquí.

No es necesario en el diccionario, si las palabras comunes se conocen a priori (ha mencionado que es un HTML). Simplemente precompute una tabla huffman utilizando datos estadísticos de muchos archivos HTML (tenga en cuenta que puede codificar una etiqueta entera con un solo símbolo, y puede tener tantos símbolos como desee).

Cuestiones relacionadas