📅  最后修改于: 2023-12-03 14:51:17.777000             🧑  作者: Mango
Rabin Karp算法是一种字符串匹配算法,用于在文本串中查找某个模式串的出现位置。它通过哈希函数来快速匹配字符窗口,可以在O(n)的时间复杂度内完成匹配。
下面我们将介绍如何在Java中使用滚动哈希来实现Rabin Karp算法。
我们首先需要实现一个哈希函数,将字符串转换为一个唯一的数字。这个数字可以用于比较两个字符串是否相等。
我们可以使用类似于多项式求值的方法来实现哈希函数,即将字符串看作一个多项式,将每个字符的ASCII码视为系数,计算出多项式的值。
下面是一个使用滚动哈希实现的字符串哈希函数:
public class RabinKarpHash {
private final int BASE = 31; // 基数
private final long MOD = (long) 1e9 + 9; // 模数
public long hash(String s) {
long hashValue = 0;
long pow = 1;
for (int i = s.length() - 1; i >= 0; i--) {
hashValue = (hashValue + pow * s.charAt(i)) % MOD;
pow = (pow * BASE) % MOD;
}
return hashValue;
}
public long rollHash(long oldHash, int len, char oldChar, char newChar) {
long newHash = (oldHash - oldChar * pow(BASE, len - 1) % MOD + MOD) % MOD;
newHash = (newHash * BASE % MOD + newChar) % MOD;
return newHash;
}
public long pow(int base, int exp) {
if (exp == 0) {
return 1;
}
long half = pow(base, exp / 2);
if (exp % 2 == 0) {
return half * half % MOD;
} else {
return half * half % MOD * base % MOD;
}
}
}
其中,hash()
方法用于计算给定字符串的哈希值,rollHash()
方法用于在滚动窗口时更新哈希值,pow()
方法用于快速计算幂。
有了哈希函数,我们现在可以开始实现Rabin Karp算法了。
我们的算法首先计算模式串的哈希值,然后在文本串中以模式串长度为窗口滚动哈希,每次比较窗口哈希值与模式串哈希值是否相等。如果相等,则说明匹配成功。
下面是一个使用滚动哈希实现的Rabin Karp算法:
public class RabinKarp {
public List<Integer> search(String pattern, String text) {
RabinKarpHash hash = new RabinKarpHash();
long patternHash = hash.hash(pattern);
int n = text.length();
int m = pattern.length();
long hashValue = 0;
List<Integer> matches = new ArrayList<>();
if (m > n) {
return matches;
}
for (int i = 0; i < m; i++) {
hashValue = (hashValue * hash.BASE + text.charAt(i)) % hash.MOD;
}
int start = 0;
while (start <= n - m) {
if (hashValue == patternHash) {
if (text.substring(start, start + m).equals(pattern)) {
matches.add(start);
}
}
if (start < n - m) {
hashValue = hash.rollHash(hashValue, m, text.charAt(start), text.charAt(start + m));
}
start++;
}
return matches;
}
}
其中,search()
方法用于在文本串中查找所有出现的模式串,返回一个包含出现位置的列表。
使用滚动哈希实现Rabin Karp算法可以在O(n)的时间复杂度内完成字符串匹配。这个算法可以处理大规模的文本串和模式串,并且在查找过程中只需要进行哈希计算和比较操作,比较高效。