Ich bin auf der Suche nach einer rollenden Hash-Funktion, so dass ich Hashes von N-Grammen einer sehr großen Zeichenfolge nehmen kann.Gibt es funktionierende Implementierungen der Rolling-Hash-Funktion, die im Rabin-Karp-String-Suchalgorithmus verwendet wird?
Zum Beispiel:
"Stackoverflow", in 5 Gramm aufgebrochen wäre:
"stack", "Tacko", "ackov", "ckove" "kover", „overf“, „verfl“, „erflo“, „rflow“
Dies ist ideal für eine roll Hashfunktion denn nachdem ich die ersten N-Gramm-Hash-Berechnung, die folgenden sind relativ billig, weil ich zu berechnen einfach den ersten Buchstaben des ersten Hashes löschen und den neuer letzter Buchstabe des zweiten Hashs.
Ich weiß, dass diese Hash-Funktion wird im allgemeinen erzeugt, wie:
H = c a k - 1 + c a k - 2 + c a k - 3 + ... + c k ein wo a ist eine Konstante und c1, ..., ck sind die Eingabezeichen.
Wenn Sie diesem Link auf der Rabin-Karp string search algorithm folgen, besagt es, dass "a" normalerweise einige große Primzahl ist.
Ich möchte meine Hashes in 32-Bit-Ganzzahlen gespeichert werden, also wie groß von einer Primzahl sollte "a" sein, so dass ich meine ganze Zahl nicht überlaufen?
Gibt es eine vorhandene Implementierung dieser Hash-Funktion irgendwo, die ich bereits verwenden könnte? Hier
ist eine Implementierung ich erstellt:
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"));
}
}
Ich bin 101 als mein bester verwenden. Ist es wichtig, ob meine Hashes überlaufen werden? Ich denke, das ist wünschenswert, aber ich bin mir nicht sicher.
Scheint dies der richtige Weg zu sein?
Warum sollte die Primzahl für diese Anwendung von der "normalen" String-Hashcode-Generierung abweichen? – CPerkins
Der Algorithmus ist einfach genug, dass er aus dem Pseudocode ziemlich einfach zu implementieren ist. Haben Sie es selbst programmiert? – MAK