Rabin Karp算法是Brute Force算法的升级版,通过计算主串中的n-m+1个子串的hash值,然后与模式串的hash值直接进行比较,避免了主串的子串与模式串的逐一比较,最好情况可以达到
O(m +n)的时间复杂度.m为模式串的长度,n为主串的长度。关键就在设计hash函数上,通过rolling hash(滚动hash)来降低时间复杂度.
下面是java实现版
/**
* rabin Karp字符串匹配算法
* @param pattern 模式串
* @param text 主串
*/
private static void rabinKarpMatch(String pattern, String text){
long hashOfPattern = hash(pattern);
int patternLength = pattern.length();
long[] textHashArray = hash(text, patternLength);
for (int i = 0; i < textHashArray.length; i++) {
if(textHashArray[i] == hashOfPattern){
int j;
for (j = 0; j < pattern.length(); j++) {
if(pattern.charAt(j) != text.charAt(j + i)){
break;
}
}
if(j == pattern.length()){
System.out.println("match:" + i);
return;
}
}
}
}
/**
* 进制数
*/
final static long seed = 10;
/**
* 滚动hash
* @param s
* @param n
* @return
*/
private static long[] hash(String text, int len){
long[] hashArray = new long[text.length() - len + 1];
hashArray[0] = hash(text.substring(0, len));
for(int i = len; i < text.length(); i++){
char newChar = text.charAt(i);
char oldChar = text.charAt(i - len);
long v = (long)((hashArray[i - len] * seed + newChar - Math.pow(seed, len) * oldChar) % Long.MAX_VALUE);
hashArray[i - len + 1] = v;
}
return hashArray;
}
private static long hash(String str){
long h = 0;
for(int i = 0; i < str.length(); i++){
h = seed * h +str.charAt(i);
}
return h % Long.MAX_VALUE;
}
public static void main(String[] args) {
String s = "398485884849494";
String p = "85";
rabinKarpMatch(p, s);
System.out.println(p.indexOf(s));
}