Estoy buscando utilizar una función hash rodante para poder tomar hashes de n-grams de una cadena muy grande.¿Hay alguna implementación funcional de la función hash rolling utilizada en el algoritmo de búsqueda de cadenas de Rabin-Karp?
Por ejemplo:
"stackoverflow", dividido en 5 gramos sería:
"pila", "tacko", "ackov", "ckove", "kover", "overf", "verfl", "erflo", "rflow"
Esto es ideal para una función hash rodadura porque después de calculo el primero de n-gramas de hash, los siguientes son relativamente baratos para calcular porque simplemente tiene que soltar la primera letra del primer hash y agregar el nueva última letra del segundo hash.
sé que en general se genera esta función hash como:
H = c un k - 1 + c un k - 2 + c un k - 3 + ... + c k a donde a es una constante y c1, ..., ck son los caracteres de entrada.
Si sigue este enlace en el Rabin-Karp string search algorithm, indica que "a" suele ser un gran primo.
Quiero que mis hashes se almacenen en enteros de 32 bits, entonces, ¿cuán grande debe ser una prima "a", de modo que no desborde mi número entero?
¿Existe una implementación existente de esta función hash en alguna parte que ya podría usar?
Aquí es una aplicación que creé:
public class hash2
{
public int prime = 101;
public int hash(String text)
{
int hash = 0;
for(int i = 0; i < text.length(); i++)
{
char c = text.charAt(i);
hash += c * (int) (Math.pow(prime, text.length() - 1 - i));
}
return hash;
}
public int rollHash(int previousHash, String previousText, String currentText)
{
char firstChar = previousText.charAt(0);
char lastChar = currentText.charAt(currentText.length() - 1);
int firstCharHash = firstChar * (int) (Math.pow(prime, previousText.length() - 1));
int hash = (previousHash - firstCharHash) * prime + lastChar;
return hash;
}
public static void main(String[] args)
{
hash2 hashify = new hash2();
int firstHash = hashify.hash("mydog");
System.out.println(firstHash);
System.out.println(hashify.hash("ydogr"));
System.out.println(hashify.rollHash(firstHash, "mydog", "ydogr"));
}
}
estoy usando 101 como mi mejor momento. ¿Importa si mis hashes se desbordarán? Creo que esto es deseable, pero no estoy seguro.
¿Esto parece ser la forma correcta de hacerlo?
¿Por qué el principal de esta aplicación sería diferente de la generación de código de cadena de caracteres "normal"? – CPerkins
El algoritmo es lo suficientemente simple como para que sea bastante fácil de implementar desde el pseudocódigo. ¿Has intentado codificarlo tú mismo? – MAK