C ++奇怪的结果-蛮力比Rabin-Karp快...?

时间:2019-12-01 14:24:16

标签: algorithm brute-force string-search rabin-karp

当前正在为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)则用了不到一秒钟的时间。蛮力花了不到拉宾卡普一半的时间,尽管对我而言这没有意义?

我是否误解了应如何应用这些算法,还是我使用的滚动哈希过程存在问题?

1 个答案:

答案 0 :(得分:1)

蛮力字符串搜索是Rabin-Karp的特例,它具有恒定的哈希函数(因此每个滚动哈希都匹配)。

两种算法的最坏情况复杂度相同,大多数“平均情况”定义的平均情况复杂度也是如此。

在这些情况下,由于计算和检查良好哈希的开销,Rabin-Karp将花费更长的时间。

与Rabin-Karp相比,暴力破解的问题在于现实生活中有时会发生恶劣的情况。例如,如果您要搜索路径名,那么您的模式可能会与文件中的许多或大多数路径名和部分路径名共同使用长前缀,这会使蛮力花费很长时间。时间。

使用Rabin-Karp,糟糕的情况在现实生活中极不可能发生。它们实际上仅在“对抗”条件下发生,在这种情况下,文件和模式是有目的地构造的,要花很长时间,并且要特别了解您使用的哈希函数。

即使如此... Rabin-Karp对于单模式搜索也不是一个很好的算法。当您同时搜索许多字符串时,它会变得非常有用,并且您可以在潜在匹配项的字典中查找滚动哈希。