Ich habe über den Rabin Karp-Algorithmus gelesen und mich immer wieder gefragt, was die große Sache ist, wenn unsere rollenden Hashes durch einen Wert Q begrenzt werden.
Ich hatte gedacht, dass unsere Ganzzahlendarstellung auf dem typischen Computer 2-Komplement ist, was genau der Begrenzung aller unserer Operationen über die rollenden Hashes durch 2 ^ 31 entspricht, sodass es mich mit anderen Worten einfach nicht interessieren sollte. Je kleiner wir binden oder haschen, desto mehr Kollisionen hätten wir. Ein größeres Q sollte also gleichbedeutend mit einer verbesserten Leistung sein!
Ich habe versucht, eine einfache (Java) Implementierung zu codieren:
public static int rabinKarp(String text, String pattern) {
if (text.length() < pattern.length()) {
return -1;
} else {
int patternHash = 0;
int textHash = 0;
int pow = 1;
// preprocessing the pattern and the first characters of the text string
for (int i = pattern.length()-1; i >= 0; --i) {
patternHash += pattern.charAt(i) * pow;
textHash += text.charAt(i) * pow;
pow *= 10;
}
pow /= 10;
// actual search
if (patternHash == textHash && areEqual(text, 0, pattern)) {
return 0;
} else {
for (int i = 1; i < text.length()-pattern.length()+1; ++i) {
textHash -= text.charAt(i-1)*pow;
textHash *= 10;
textHash += text.charAt(i+pattern.length()-1);
if (textHash == patternHash && areEqual(text, i, pattern)) {
return i;
}
}
return -1;
}
}
}
Nach einigen vorläufigen Tests scheint meine Hypothese empirisch korrekt zu sein, aber ich habe sie nirgendwo geschrieben gesehen, also wundere ich mich.
Vermisse ich etwas