He estado buscando una implementación eficiente de String trie. Principalmente he encontrado un código como este:
Implementación referencial en Java (según wikipedia)
No me gustan estas implementaciones principalmente por dos razones:
- Solo admiten 256 caracteres ASCII. Necesito cubrir cosas como cirílico.
- Son extremadamente ineficientes de memoria.
Cada nodo contiene una matriz de 256 referencias, que son 4096 bytes en una máquina de 64 bits en Java. Cada uno de estos nodos puede tener hasta 256 subnodos con 4096 bytes de referencias cada uno. Por lo tanto, un Trie completo para cada cadena de caracteres ASCII 2 requeriría un poco más de 1 MB. Tres cadenas de caracteres? 256 MB solo para matrices en nodos. Y así.
Por supuesto, no tengo la intención de tener 16 millones de cadenas de tres caracteres en mi Trie, por lo que se desperdicia mucho espacio. La mayoría de estas matrices son solo referencias nulas, ya que su capacidad supera con creces el número real de claves insertadas. Y si agrego unicode, las matrices se vuelven aún más grandes (char tiene valores de 64k en lugar de 256 en Java).
¿Hay alguna esperanza de hacer un trie eficiente para cuerdas? He considerado un par de mejoras sobre este tipo de implementaciones:
- En lugar de usar una matriz de referencias, podría usar una matriz de tipo entero primitivo, que se indexa en una matriz de referencias a nodos cuyo tamaño es cercano al número de nodos reales.
- Podría dividir cadenas en partes de 4 bits que permitirían matrices de nodos de tamaño 16 a costa de un árbol más profundo.
si codifica las cadenas en UTF8, puede usar el trie de ramificación 256 estándar y seguir siendo compatible con Unicode
también debe tener en cuenta que solo 70 caracteres de los 128 caracteres ascii posibles (que todos codifican a 1 byte en UTF8) se encontrarán con mayor frecuencia que puede optimizar para eso (como incluir los dígrafos comunes en lugar de los caracteres de control no utilizados )
fuente
byte*
para codificar cualquier tipo en un trie bit a bit.