|
Is it possible to determine what value to select for the nBitsPerSample property based on the source file?
|
|
|
|
|
I got an error on downloading the source file.
|
|
|
|
|
When I tried use on 8bits per sample, the decompressor always fail.
I'm using a 800 x 800 unsigned char picture.
Am I doing anything wrong?
Thanks
|
|
|
|
|
This is a great inspiring article. I am pretty much pleased with your good work. You put really very helpful information. Keep it up once again.
|
|
|
|
|
Se me ocurre una variante de este método para archivos binarios:
Esta consiste en que se tomen grupos de N bits y se vayan insertando en un diccionario. El diccionario también guardaría el número de veces que ha aparecido cada grupo. Luego se tomarían los primeros M grupos de N bits (que se repitan más veces) y se haría la compresión con base en ellos. Se podría utilizar un bit indicador de grupo comprimido o no comprimido, dentro del archivo comprimido. Si está comprimido, se insertaría (o leería) el siguiente código de grupo y si no está comprimido, se insertaría (o leería) el siguiente grupo de N bits no comprimidos. En la cabecera del archivo comprimido, se insertarían los grupos de N bits comprimidos y el código correspondiente, sería el orden en que se encuentra el grupo dentro de la cabecera.
M podría ser igual, a lo sumo, a N - 2, pues no tiene sentido que sea igual a N, pues abarcaría todos los grupos y tampoco tendría sentido que sea igual a N - 1, pues el bit que se ganaría, se perdería con el bit indicador de grupo comprimido o no comprimido. (Aunque también habría que considerar el tamaño de la cabecera y el número de bits colocados adicionalmente, con los indicadores de grupo comprimido o no comprimido).
Usted podría calcular el valor de N dinámicamente, verificando con cual valor se obtiene un número promedio de grupos de N bits, mayor o igual que 3 (por decir un número razonable). Por ejemplo, si un archivo tiene mil bits, entonces:
x = número de grupos de N bits
1000/x >= 3
-> 1000/3 >= x
-> x = 333.33
Si se divide 1000/333, se obtiene 3.003 y si se divide 100/334, se obtiene 2.994. Por lo tanto, se redondea x a 333, pues 1000/333 >= 3 y no así 1000/334.
Para calcular el número de bits que requiere 333, se calcula el logaritmo en base 2 de 333:
log2(333) = 8.38
2^8 = 256 y 2^9 = 512. Por lo tanto, el número 333 cabe en 9 bits.
Ahora bien, 1000/512 = 1.95, mientras que 1000/256 = 3.9. Por lo tanto, N debe ser igual a 8 bits y no a 9 bits.
M podría ser igual a N - 3. Por lo tanto, en este caso, M = 5 bits.
Ahora bien, este cálculo de M tiene el problema de que conforme N crezca, el valor porcentual de M se va acercando al 100% de N. Por ejemplo, si N = 100, M = N - 3 = 97 (el 97% de N). Así que otra forma de calcular el valor de M, es asignarle un valor porcentual de N. Así si N = 100 y M = 50% de N, entonces M = 50.
Por otra parte, conforme el archivo por comprimir crezca, el valor porcentual de los bits indicadores de bloque comprimido y bloque no comprimido, con respecto al tamaño total del archivo, tiende hacia 0. Por ejemplo, con grupos de 10 bits, con el bit indicador pasan a ser de 11 bits (un 10% adicional), mientras que con grupos de 50 bits, con el bit indicador pasan a ser de 51 bits (un 2% adicional).
Además, conforme el tamaño del archivo comprimido sea más grande, el tamaño del encabezado es, proporcionalmente, cada vez más pequeño. Por ejemplo, en este caso, el tamaño del archivo comprimido es aproximadamente (2^N)*3, mientras que el tamaño del encabezado es (2^M)*N. Para N = 8 y M = 4, esto equivale a (2^8)*3 y (2^4)*8. Si se divide (2^4)*8 entre (2^8)*3, se obtiene 128/768 que es igual a 0.1667 (el 16.67%). Para N = 20 y M = 10, esto equivale a (2^20)*3 y (2^10)*20. Si se divide (2^10)*20 entre (2^20)*3, se obtiene 20480/3145728 que es igual a = 0.0065 (el 0.65%). Para N = 29 y M = 14, esto equivale a (2^29)*3 y (2^14)*29. Si se divide (2^14)*29 entre (2^29)*3, se obtiene 475136/1610612736 que es igual a = 0.000295 (el 0.0295%).
En realidad aquí me equivoqué con el cálculo del número de veces en que se repite N en el archivo. Para que se repita 3 veces, se debe realizar la siguiente operación: (2^N)*N*3. Si N = 8, esto equivale a (2^8)*8*3 = 6144. Para que se repita una vez, se debe realizar la operación: (2^N)*N, que con N = 8 equivale a (2^8)*8 = 2048. Si se divide (2^N)*3 entre (2^N)*N, con N = 8, esto equivale a ((2^8)*3)/((2^8)*8) = 768/2048 = 0.375 (el 37.5%). Esto significa que en un archivo de 768 bits, se usa el 37.5% de todas las combinaciones posibles de números de 8 bits. El cálculo también se puede hacer dividiendo ((2^N)*3)/N que con N = 8 es igual a ((2^8)*3)/8 = 96 y luego dividiendo 96/(2^N) que con N = 8 es igual a 96/(2^8) = 0.375.
El número de bits indicadores de bloque comprimido o no comprimido, con tres repeticiones, es igual a (2^N)*1*3 y con una repetición es igual a (2^N)*1*1. Si se divide (2^N)*1*3 entre (2^N)*N*3, se obtiene 1/N, que con N = 10 bits, equivale a 1/10 = 0.1 (el 10%), mientras que con N = 20 bits, equivale a 1/20 = 0.05 (el 5%). Lo mismo ocurre con (2^N)*1*1 entre (2^N)*N*1.
El tamaño proporcional del encabezado, también disminuye mucho, pues con una repetición es igual a ((2^M)*N)/((2^N)*N), que con N = 8 y M = 4, es igual a ((2^4)*8)/((2^8)*8) = 0.0625 (el 6.25%). Con 3 repeticiones es igual a ((2^M)*N)/((2^N)*N*3), que, con estos mismos valores de N y de M, es igual a ((2^4)*8)/((2^8)*8*3) = 0.0208 (el 2.08%).
Para calcular el valor de N, se puede comenzar calculando el logaritmo en base 2 del tamaño total del archivo por comprimir. Así por ejemplo si el archivo mide mil bits, entonces log2(1000) = 9.97. Si se comienza con N = 10 y se usa un tamaño promedio de 3 veces, entonces:
(2^10)*10*3 = 30720 (muy grande).
(2^9)*9*3 = 13824 (todavía muy grande).
(2^8)*8*3 = 6144 (todavía muy grande).
(2^7)*7*3 = 2688 (todavía mayor que 1000).
(2^6)*6*3 = 1152 (todavía mayor que 1000).
(2^5)*5*3 = 480 (480 es menor o igual que 1000). Por lo tanto, N debe ser igual a 5 bits.
Con un número promedio de repeticiones de 3 veces, se podría escoger el valor de M hasta que se cumpla la condición de que se hayan tomado todos los grupos que se repiten al menos 4 veces. (4 = 3+1 repeticiones de grupos de N bits). De esta forma, M nunca superaría el 50% del valor de N).
Otra forma de calcular el valor de M, consiste en que cada vez en que el número de decimales de log2(X) sea igual a 0, se efectúe la operación ((2^M)*X + R)/((2^N)*N*3). X es igual al número acumulado de veces que se repiten los códigos de M bits, empezando desde los grupos de N bits que se repiten más veces, hasta los que se repiten menos veces. M sería igual a log2(X). R es igual al tamaño restante del archivo, que se calcularía como: ((2^N)*N*3 - N*X). Se tomaría el valor de M que minimice la relación. Para no tener que hacer el cálculo de M, cada vez que se incremente el valor de X en 1, se podría hacer cada vez que se duplique el valor de X. En este caso, M siempre se incrementaría en 1.
El algoritmo podría ser algo similar al siguiente:
M = -1
X = 0
m_iMejorValorM = M
m_iMejorValorX = X
m_dMejorRelacion = 1
m_iNumGruposNBits = 0
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
while m_bQuedanGruposNBits
m_iNumGruposNBits += 1
X += m_iNumVecesRepite
M = ceiling(log2(m_iNumGruposNBits))
m_dNuevaRelacion = CalcularRelacion(N, M, X)
if m_dNuevaRelacion < m_dMejorRelacion then
m_dMejorRelacion = m_dNuevaRelacion
m_iMejorValorM = M
m_iMejorValorX = X
end if
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
end while
En realidad, M es un valor que puede encontrarse entre 0 y ceiling(log2(X)). La explicación es que si la primera palabra se repite 15 veces, X = 15, mientras que M es igual a 0 (no a ceiling(log2(X)) = 4).
La fórmula original es: ((2^M)*X + R)/((2^N)*N*3), que es igual a: ((2^M)*X + (2^N)*N*3 - N*X)/((2^N)*N*3), que es igual a: ((2^M)*X - N*X + (2^N)*N*3)/((2^N)*N*3), que es igual a: ((2^M)*X - N*X)/((2^N)*N*3) + ((2^N)*N*3)/((2^N)*N*3), que es igual a: ((2^M)*X - N*X)/((2^N)*N*3) + 1, que es igual a: ((2^M - N)*X)/((2^N)*N*3) + 1. Independientemente del valor que tome X, el resultado de la función es menor que 1, mientras 2^M - N < 0. (N es una constante que se calcula antes de iniciar el algoritmo y M es una variable que se va incrementando durante el transcurso del algoritmo). Por lo tanto, en el momento en que 2^M - N >= 0, se puede concluir la ejecución del algoritmo.
De esta forma, el algoritmo se podría reescribir como:
M = -1
X = 0
m_iMejorValorM = M
m_iMejorValorX = X
m_dMejorRelacion = 1
m_iNumGruposNBits = 0
m_iNumVecesRepite = 0
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
m_bSePuedeTerminar = false
while m_bQuedanGruposNBits andalso not m_bSePuedeTerminar
m_iNumGruposNBits += 1
X += m_iNumVecesRepite
M = ceiling(log2(m_iNumGruposNBits))
m_dNuevaRelacion = CalcularRelacion(N, M, X, m_bSePuedeTerminar)
if m_dNuevaRelacion < m_dMejorRelacion then
m_dMejorRelacion = m_dNuevaRelacion
m_iMejorValorM = M
m_iMejorValorX = X
end if
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
end while
Ahora bien, supongamos que N = 25, que M = 5 y que X es igual a 100. N*X = 25*100 = 2500. Por su parte, (2^M)*X = (2^5)*100 = 32*100 = 3200. Como se puede observar, en este caso (2^M)*X > N*X, lo cual equivale a decir que (2^M) > N y que (2^M) - N > 0. Esto no sucede si M = 4, pues en este caso (2^M)*X = (2^4)*100 = 16*100 = 1600. En este caso si se cumple que (2^M)*X < N*X -> (2^M) < N -> (2^M) - N < 0. Esto se da porque con N = 25, se ocupan 5 bits, sin embargo 25 < 2^5 -> 25 < 32. Esto no ocurre con 2^4, pues 25 > 2^4 -> 25 > 16. De allí que se utilice:
M = ceiling(log2(m_iNumGruposNBits))
en vez de...
M = floor(log2(m_iNumGruposNBits))
Esto por cuanto si N = 25 y m_iNumGruposNBits = 16, entonces M = ceiling(log2(m_iNumGruposNBits)) -> M = 4 y 2^M = 2^4 -> 2^M = 16 -> 2^M < N -> 2^M - N < 0. En cambio si N = 25 y m_iNumGruposNBits = 17, entonces M = ceiling(log2(m_iNumGruposNBits)) -> M = 5 y 2^M = 2^5 -> 2^M = 32 -> 2^M > N -> 2^M - N > 0.
Por otra parte, hay que probar mientras 2^M - N < 0, independientemente del valor de X. Esto por cuanto si:
a) M = 3, N = 25 y X = 104, entonces (2^M - N)*X = (2^3 - 25)*104 = (8 - 25)*104 = -17*104 = -1768.
b) M = 4, N = 25 y X = 117, entonces (2^M - N)*X = (2^4 - 25)*117 = (16 - 25)*117 = -9*117 = -1053. -1768 < -1053. Por lo tanto, el caso "a" es mejor que el caso "b".
c) M = 4, N = 25 y X = 208, entonces (2^M - N)*X = (2^4 - 25)*208 = (16 - 25)*208 = -9*208 = -1872. -1872 < -1768. Por lo tanto, el caso "c" es mejor que el caso "a".
Ahora bien, tenemos que la fórmula es: ((2^M - N)*X)/((2^N)*N*3) + 1. Si a esto se le suma el espacio que ocupan los bits indicadores de bloque comprimido o no comprimido (que es igual a 1/N), la fórmula pasa a ser: ((2^M - N)*X)/((2^N)*N*3) + 1 + 1/N. Si el valor resultante, al evaluar esta fórmula, es menor que 1, entonces se comprime el archivo. En caso contrario, no se comprime.
Ahora bien, la fórmula: ((2^M - N)*X)/((2^N)*N*3) + 1 + 1/N, se puede evaluar dentro de la función: "CalcularRelacion" que se encuentra en el algoritmo aquí descrito. Sin embargo, a la variable "m_bSePuedeTerminar" se le puede asignar el valor "true", solo cuando 2^M - N < 0. Esto por cuanto "1/N" es una constante y "((2^M - N)*X)/((2^N)*N*3)" es una variable cuyo valor se puede ir decrementando durante el ciclo del algoritmo. Así se puede dar el caso en que la función retorne un valor mayor o igual que 1, pero este caso nunca ingresará al bloque de código que se encuentra dentro de la condición "if m_dNuevaRelacion < m_dMejorRelacion then", pues "m_dMejorRelacion" se inicia en 1, antes de iniciar el ciclo del algoritmo.
Considerando el tamaño proporcional de encabezado, la fórmula podría convertirse en: ((2^M - N)*X)/((2^N)*N*3) + 1 + 1/N + ((2^M)*N)/((2^N)*N*3).
En realidad me equivoqué con la fórmula: M es el número de bits que ocupan los códigos comprimidos. Por otra parte, se puede usar una variable "G" que indique el número de grupos de N bits que hay en el encabezado. Así la fórmula pasaría a ser:
((M - N)*X)/((2^N)*N*3) + 1 + 1/N + (G*N)/((2^N)*N*3).
que sería igual a:
((M - N)*X + G*N)/((2^N)*N*3) + 1 + 1/N
y el algoritmo sería el siguiente:
M = 0
X = 0
G = 0
m_iMejorValorM = M
m_iMejorValorG = G
m_dMejorRelacion = 1
m_iNumVecesRepite = 0
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
m_bSePuedeTerminar = false
while m_bQuedanGruposNBits andalso not m_bSePuedeTerminar
G += 1
X += m_iNumVecesRepite
if G = 1 then
M = 1
else
M = ceiling(log2(G))
end if
m_dNuevaRelacion = CalcularRelacion(N, M, X, G, m_bSePuedeTerminar)
if m_dNuevaRelacion < m_dMejorRelacion then
m_dMejorRelacion = m_dNuevaRelacion
m_iMejorValorM = M
m_iMejorValorG = G
end if
m_bQuedanGruposNBits = DemeSiguienteGrupoNBits(m_iNumVecesRepite)
end while
M = ceiling(log2(G)), pues ese es el espacio, en bits, que ocupan los "G" grupos de "N" bits que se van a comprimir. log2(1) es igual a 0, sin embargo, si hay un grupo, se ocupa un bit y M debe ser igual, en este caso, a 1.
El ciclo se repetiría mientras ((M - N)*X + G*N)/((2^N)*N*3) sea menor que 0, pues M, X y G comienzan en un valor mayor o igual que 1, la primera vez que se calcula la relación y se van incrementando durante el transcurso del algoritmo.
Se ocupa la variable "m_iMejorValorG", pues indica cuántos grupos de "N" bits hay en el encabezado. También se ocupa la variable "m_iMejorValorM", pues indica el tamaño, en bits, que ocupa cada grupo comprimido.
En la relación también se podrían sumar los bits que ocupan los campos del encabezado, que podrían ser, el número de versión, el valor de G, el valor de N y el tamaño del archivo. Si el tamaño del campo de número de versión es de 8 bits, el tamaño del campo del valor de G es de 32 bits, el tamaño del campo del valor de N es de 8 bits y el tamaño del campo del tamaño del archivo es de 32 bits, estos datos suman 80 bits. Estos bits no se sumarían en la ecuación ((M - N)*X + G*N)/((2^N)*N*3), pues si M = 1, N = 10, X = 7 y G = 1, entonces (M - N)*X + G*N + 80) = (1 - 10)*7 + 1*10 + 80 = -9*7 + 90 = -63 + 90 = 27 y 27 es mayor que 0. En cambio si M = 1, N = 10, X = 14 y G = 2, entonces (M - N)*X + G*N + 80) = (1- 10)*14 + 2*10 + 80 = -9*14 + 20 + 80 = -126 + 100 = -26 y -26 si es menor que 0.
También el ciclo se podría repetir mientras la ecuación ((M - N)*X + G*N) sea menor que 0, pues, independientemente del valor que tome ((2^N)*N*3), que siempre es mayor que 0, el signo de la ecuación ((M - N)*X + G*N)/((2^N)*N*3) es igual al signo de la ecuación ((M - N)*X + G*N).
Así, la relación pasaría a ser, en este caso, igual a:
((M - N)*X + G*N + 80)/((2^N)*N*3) + 1 + 1/N.
y el ciclo se repetiría mientras:
((M - N)*X + G*N) < 0.
No hace falta incorporar el campo del valor de M en el encabezado, pues es igual a ceiling(log2(G)), o bien, es igual a 1, cuando ceiling(log2(G)) = 0.
El peor caso, es que X sea igual a 3 (pues el número promedio de repeticiones, según este algoritmo, es de 3), en cuyo caso, si M = 1 y G = 1, entonces:
((M - N)*X + G*N) = ((1 - N)*3 + 1*N) = 3 - 3*N + 1*N = 3 - 2*N. Esto es menor que 0, si N es mayor o igual que 2.
modified 30-Dec-12 13:10pm.
|
|
|
|
|
This is an English speaking site.
All posts should be in English (Except in dedicated forums like GIT and GCT).
Thanks.
|
|
|
|
|
Well, you could use the Google translator. The display language is Spanish.
|
|
|
|
|
I think you adhering to the site rules is probably the correct way to go.
If you write in your best english, then ask the editors to review, they will sort out the problems.
|
|
|
|
|
You also may try the Google Chrome. It can do automatic translations.
|
|
|
|
|
I write in Spanish, because I'm not used to write in English.
|
|
|
|
|
En cualquier idioma a lo sumo se usan unas 10 mil palabras, así que se le podría asignar un número a cada palabra y usarlo en reemplazo de esta, al momento de hacer la compresión.
Se podría indicar en el encabezado del texto comprimido, el tamaño del índice de palabras con el que se va a trabajar, para que cuando crezca, se le pueda indicar al texto comprimido, otro tamaño del índice y se puedan codificar más palabras.
Con todo esto, todavía existe el problema de cuáles caracteres están en minúscula y cuáles en mayúscula. Este problema se podría resolver si se le anexa al archivo comprimido, un mapa de bits, donde cada bit indique si el caracter correspondiente está en minúscula o en mayúscula. De esta forma, si se usan 8 bits para representar cada caracter no comprimido, el tamaño de este mapa de bits sería de una octava parte del tamaño del archivo original.
Cada palabra comprimida o cada palabra no comprimida, podría ser precedida por un bit, el cual le permitiría al algoritmo de descompresión, distinguir entre ambas. En específico, cada palabra no comprimida podría corresponder a un único caracter.
Para que el número de palabras por procesar al mismo tiempo no sea muy grande, se podría especificar en el encabezado del archivo comprimido, el conjunto de caracteres que se va a utilizar. En el caso de una página web, esto se podría incorporar como atributo, en un elemento de bloque (que podría ser "div" o "table", por ejemplo). Esto permitiría, por ejemplo, que se combine un artículo en español, sobre algún algoritmo de programación, con código fuente de un lenguaje de programación. Para que se puedan modificar fácilmente las páginas web, el atributo del conjunto de caracteres, se podría incorporar dentro del atributo "style" del elemento, o bien, dentro de una hoja de estilos. Se podrían diseñar nuevos conjuntos de caracteres y cada uno comprendería solo las letras del alfabeto en que está escrito el texto.
modified 21-Dec-12 8:33am.
|
|
|
|
|
sí, pero usted tiene que elegir códigos dependiendo de la frecuencia de uso las palabras. así, puede reducir el tamaño mediante el uso de s pequeños de código para la frecuencia de palabras de alta.
Saludos cordiales
|
|
|
|
|
El código es el número de palabra. Los números de las palabras se encontrarían en binario. Así por ejemplo, en 20 bits se podrían guardar 2^20 palabras (más de un millón de palabras) y se gastarían menos de 3 bytes por palabra. La frecuencia de uso de las palabras no importa. La asociación entre el número y la palabra, se podría guardar en una base de datos.
modified 21-Dec-12 8:50am.
|
|
|
|
|
Usted puede crear un programa que abra un archivo de texto, en algún idioma, e inserte todas las palabras que se encuentran allí, en una base de datos.
|
|
|
|
|
Pero, esta forma de compresión no es eficiente. Como se trata de datos de texto y sólo en función del idioma del texto. LZW puede comprimir y tipo de datos, independientemente del formato de datos o lenguaje, incluso se puede comprimir texto en varios idiomas.
Siempre prefiero la simplicidad y generalidad código en código especial con mejor ratio de compresión.
|
|
|
|
|
Generalmente los documentos se guardan en un solo idioma, por lo cual, es más eficiente cargar la tabla de palabras en ese idioma, que podría ser de un tamaño de 10 mil palabras, que cargar una tabla para todos los idiomas, que podría incluir hasta un millón de palabras. De todos modos, usted puede dividir el texto en fragmentos, de tal forma que cada fragmento esté en un idioma distinto y lo más frecuente es que un texto esté escrito en uno o dos idiomas a lo sumo.
Por otra parte, 10 mil palabras caben en 14 bits, mientras que un millón de palabras necesitan 20 bits, por lo cual, el archivo comprimido es mucho más pequeño si los códigos son de 14 bits.
Ahora bien, usted podría guardar palabras de 3 o más letras en el diccionario (o base de datos), para hacer más pequeña la base de datos y ocupar menos bits para la compresión. Las palabras de 1 o 2 caracteres, las podría dejar sin comprimir. (A menos que un idioma necesite 16 bits por caracter, en cuyo caso, podría guardar palabras de 2 o más letras en el diccionario o base de datos).
Ahora bien, usted también podría insertar palabras de 2 caracteres en la base de datos, en un idioma que necesite 8 bits por caracter, para saber cuántas son. Si son muchas, entonces guardaría palabras de 3 o más caracteres.
Por otra parte, en una base de datos que use el algoritmo de búsqueda binaria para buscar un número (o código) de palabra en una tabla, necesita hacer a lo sumo 14 saltos por cada código en una tabla de 2^14 palabras, mientras que en una tabla de 2^20 palabras se necesitan hacer hasta 20 saltos para encontrar un código. Por lo tanto, es más eficiente tener tablas de 2^14 registros, que tablas de 2^20 registros.
Ahora bien, usted también podría insertar las palabras de todos los tamaños que quiera, en una base de datos de SQL Server, para saber cuántas hay por tamaño. De esta forma, a la hora de copiar las palabras en una base de datos de Microsoft Access, usted podría decidir a partir de cuál tamaño quiere insertar en la tabla correspondiente y esa información la podría guardar en una constante por idioma, en su aplicación.
Otra forma de decidir cuáles palabras insertar en una tabla de una base de datos de Microsoft Access, consiste en añadirle un campo a la tabla de SQL Server, que indique cuántas veces se ha encontrado determinada palabra entre todos los documentos revisados. De esta forma, se seleccionarían solo aquellas palabras cuyo número porcentual de veces sea mayor o igual que el especificado en una constante, por idioma, de su aplicación. Así se manejaría la frecuencia de uso. Una ventaja que tiene esto, es que no habría que revisar si en los archivos revisados aparecen nombres de personas, lugares o cosas, pues se repetirían muy pocas veces, entre todos los documentos revisados. Cada vez que cambie esa constante, habría que modificar el campo de número de versión del idioma, en el archivo comprimido y si se cambia muchas veces, el número de versión se incrementaría mucho. Otra forma de enfrentar el problema, consiste en agregar un campo de fecha, por idioma, al archivo comprimido, que especifique la fecha en que fue modificada, por última vez, la tabla correspondiente en la base de datos de Microsoft Access.
Si usted comprime varios archivos, basándose en la frecuencia de uso de las palabras, podría guardar la base de datos de Microsoft Access que se usó, junto con los archivos comprimidos y a la hora de descomprimir esos archivos, podría especificarle a la aplicación, la ubicación de esa base de datos. Otra forma de manejar este problema, consiste en poner todas las versiones de bases de datos de Microsoft Access que se crearon, en un servidor, de tal forma que quien quera descomprimir cualquier archivo, pueda descargar de allí la versión que necesita.
|
|
|
|
|
Para una tabla que tiene un millón de palabras, los caracteres son de 8 bits y cada palabra mide en promedio 6 caracteres, su tamaño es de:
Tamaño por registro:
6 caracteres * 8 bits (del tamaño de cada palabra) = 48 bits.
+ 32 bits para el número o código de la palabra.
Para un total de 80 bits.
80 bits multiplicado por un millón de palabras, es igual a 80 millones de bits.
En cambio, una tabla que tiene 10 mil palabras, gasta 16 bits para el número o código de palabra. Esto sumado a 48 bits del tamaño promedio de cada palabra, da un tamaño total de 64 bits por registro. 64 bits multiplicado por 10 mil palabras, es igual a 640 mil bits.
Evidentemente, una tabla de 10 mil palabras, es mucho más pequeña que una tabla de un millón de palabras.
Por otra parte, para hacer una búsqueda binaria sobre un índice de una tabla, es necesario cargar todo el índice. Sin importar si el índice corresponde al número de palabra o a la palabra, el número de registros por cargar, es igual al número de registros que tiene la tabla y es mucho mejor cargar un índice de 10 mil registros, que un índice de un millón de registros.
modified 25-Dec-12 7:06am.
|
|
|
|
|
Por otra parte, si se mezclan todos los idiomas en una sola tabla, puede ocurrir que se tengan que usar caracteres de 16 bits, que abarquen el alfabeto en todos los idiomas. Esa es otra razón por la cual es mejor poner cada idioma en una tabla distinta, pues así habrá en unas tablas, caracteres de 8 bits y en otras tablas, caracteres de 16 bits.
|
|
|
|
|
Después del bit que diferencia las palabras codificadas de las no codificadas y que indica que sigue una palabra no codificada, se podría agregar otro bit que indique si la palabra es de 8 o 16 bits. En este caso, las palabras no codificadas serían caracteres únicos.
|
|
|
|
|
Usted podría hacer las inserciones de las palabras en una base de datos de SQL Server, por ejemplo, para que puedan trabajar varias personas a la vez. Luego podría hacer un programa que copie las palabras en esa base de datos, a una base de datos de Microsoft Access, la cual tendría cada persona que se intercambie documentos comprimidos.
|
|
|
|
|
LZW construye su diccionario sobre la marcha, sin necesidad de guardar cualquier cosa. Y esta es la magia de LZW.
|
|
|
|
|
El punto es que si usted quiere compartir un archivo con otra persona, ambos tienen que tener el mismo diccionario y yo me valdría de una base de datos de Microsoft Access, para guardar ese diccionario.
|
|
|
|
|
Usted también podría valerse de un corrector ortográfico, antes de procesar un documento de texto, para saber si no hay faltas de ortografía, o bien, palabras en otros idiomas, dentro del documento.
|
|
|
|
|
sí, este es un buen punto.
|
|
|
|
|
Usted podría programar un algoritmo como el siguiente, para capturar las palabras que se encuentran en un texto y que se van a insertar en una base de datos:
m_sCaracteresValidos = "abcdefghijklmnopqrstuvwxyz"
m_sPalabra = ""
m_sSiguienteCaracter = lcase(SiguienteCaracter())
while trim(m_sSiguienteCaracter) <> "" _
andalso instr(m_sCaracteresValidos, m_sSiguienteCaracter) = 0
m_sSiguienteCaracter = lcase(SiguienteCaracter())
end while
while trim(m_sSiguienteCaracter) <> "" _
andalso instr(m_sCaracteresValidos, m_sSiguienteCaracter) > 0
m_sPalabra &= m_sSiguienteCaracter
m_sSiguienteCaracter = lcase(SiguienteCaracter())
end while
return m_sPalabra
modified 28-Dec-12 10:17am.
|
|
|
|
|