【发布时间】:2020-03-26 07:52:55
【问题描述】:
目前正在为一个 uni 模块开发一个字符串搜索程序,并且我已经成功地实现了这些算法,至少到了他们能够始终如一地找到字符串的程度。我实现了 Boyer Moore 和 Rabin Karp。当我的一个同学遇到这个确切的问题时,我也投入了蛮力,并意识到我遇到了同样的问题 - 蛮力比单词列表上的 Rabin-Karp 更快。
Rabin-Karp 似乎花费了最多时间来执行滚动哈希,起初我很好奇我是否只是有很多碰撞,但我设法用一个巨大的素数将碰撞减少到 3。由于质数的大小,我假设这增加了一点时间,但滚动散列导致问题似乎很明显。
这是滚动哈希部分:
//hashes don't match, rehash using rolling hash to move on to next string section
if (counter < (stringLength - patternLength)) {
stringHash = (MAXCHAR *(stringHash - stringFile[counter] * hash) + stringFile[counter + patternLength]) % prime;
if (stringHash < 0) {
stringHash += prime; //when hash value is negative, make it positive
}
}
if (!found) {
counter++;
}
我想尝试搜索一个巨大的文本文件,所以我使用了 Rockyou 词汇表,Boyer Moore 对此非常满意,而 Rabin-Karp 只用了不到一秒钟。蛮力花费的时间不到 Rabin-Karp 的一半,尽管这对我来说没有意义?
我是否误解了应该如何应用这些算法,或者我正在使用的滚动哈希过程是否存在问题?
【问题讨论】:
-
顺序表示法省略了常数。如果常数对于 O(1) 来说足够高,那么在 n 变得足够大之前,具有低常数的 O(n) 会更慢。确保您的实现是正确的,并且您正在使用足够大的数据集进行测试。
标签: algorithm brute-force string-search rabin-karp