Algorithm C++;奇怪的结果-蛮力比拉宾·卡普快。。。?

Algorithm C++;奇怪的结果-蛮力比拉宾·卡普快。。。?,algorithm,brute-force,string-search,rabin-karp,Algorithm,Brute Force,String Search,Rabin Karp,目前正在为一个uni模块开发一个字符串搜索程序,我已经成功地实现了这些算法,至少到了一致地找到字符串的程度。我实现了Boyer Moore和Rabin Karp。当我的一个同学遇到这个问题时,我也投入了蛮力,并意识到我也遇到了同样的问题——蛮力比单词表上的拉宾·卡普(Rabin Karp)更快 Rabin Karp似乎花了最多的时间执行滚动散列,一开始我很好奇是否有很多碰撞,但我设法用一个巨大的素数将碰撞减少到3。我假设由于素数的大小,这会增加一点时间,但很明显,滚动散列是造成问题的原因 这是滚

目前正在为一个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++; 
        }

//散列不匹配,请使用滚动散列重新哈希以转到下一个字符串部分
如果(计数器<(stringLength-patternLength)){
stringHash=(MAXCHAR*(stringHash-stringFile[counter]*hash)+stringFile[counter+patternLength])%prime;
if(stringHash<0){
stringHash+=prime;//当哈希值为负数时,将其设为正数
}
}
如果(!找到){
计数器++;
}
我想尝试搜索一个巨大的文本文件,所以我使用了rockyou单词表,Boyer Moore对此非常满意,Rabin Karp正在使用第二个。暴力只花了拉宾·卡普不到一半的时间,但这对我来说毫无意义


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

暴力字符串搜索是Rabin Karp的特例,具有常量哈希函数(因此每个滚动哈希都匹配)

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

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

与拉宾·卡普(Rabin Karp)相比,暴力的问题在于,现实生活中有时会发生糟糕的情况。例如,如果您正在搜索路径名,那么您的模式可能与文件中的许多或大多数路径名和部分路径名有一个长前缀,这将使暴力需要很长时间

在拉宾·卡普(Rabin Karp)的帮助下,现实生活中不太可能发生糟糕的情况。它们只会在“敌对”条件下发生,在这种情况下,文件和模式的构建是有目的的,需要花费很长的时间,并且需要了解您使用的哈希函数


即便如此。。。Rabin-Karp并不是一个伟大的单模式搜索算法。当您同时搜索多个字符串,并且可以在潜在匹配的字典中查找滚动哈希时,它会变得更加有用。

顺序表示法忽略了常量。如果常数对于O(1)来说足够高,那么对于具有低常数的O(n),它将变慢,直到n变得足够大。确保您的实现是正确的,并且您正在使用足够大的数据集进行测试。嗨,Matt,谢谢您的回答。这让我尝试使用不同的数据集,以使bruteforce表现糟糕(我使用了大约100万个以“ja”结尾的“a”字符,并让模式搜索为“aaaaaaaa-ja”,而yup Rabin Karp比蛮力要好一点,就像你用公共前缀所说的那样。Boyer-Moore在这个数据集上是最差的-我认为这种类型的搜索是Boyer-Moore最差的情况吗?Boyer-M唯一真正糟糕的情况oore是模式多次出现的时候。您的情况还不错,但它会破坏优化,所以不能跳过。