Rabin Karp算法的一点修改版本的可行性

时间:2017-09-13 15:41:52

标签: algorithm python-3.x hash

我正在尝试实施Rabin Karp算法的一点修改版本。我的想法是,如果我根据与每个字母相关的权重得到给定模式的哈希值,那么我不必担心字谜,所以我可以拿起字符串的一部分,计算其哈希值并且与传统方法的模式的哈希值进行比较,其中计算字符串和模式的两部分的哈希值,然后检查它们是否实际相似或者它可以是字谜。这是我的代码

string = "AABAACAADAABAABA"
pattern = "AABA"
#string = "gjdoopssdlksddsoopdfkjdfoops"
#pattern = "oops"

#get hash value of the pattern
def gethashp(pattern):
    sum = 0
    #I mutiply each letter of the pattern with a weight
    #So for eg CAT will be C*1 + A*2 + T*3 and the resulting
    #value wil be unique for the letter CAT and won't match if the
    #letters are rearranged
    for i in range(len(pattern)):
        sum = sum + ord(pattern[i]) * (i + 1)
    return sum % 101 #some prime number 101

def gethashst(string):
    sum = 0
    for i in range(len(string)):
        sum = sum + ord(string[i]) * (i + 1)
    return sum % 101

hashp = gethashp(pattern)
i = 0
def checkMatch(string,pattern,hashp):
    global i 
    #check if we actually get first four strings(comes handy when you 
    #are nearing the end of the string)
    if len(string[:len(pattern)]) == len(pattern):
        #assign the substring to string2
        string2 = string[:len(pattern)]
        #get the hash value of the substring
        hashst = gethashst(string2)
        #if both the hashvalue matches
        if hashst == hashp:
            #print the index of the first character of the match
            print("Pattern found at {}".format(i))
        #delete the first character of the string
        string = string[1:]
        #increment the index
        i += 1 #keep a count of the index
        checkMatch(string,pattern,hashp)
    else:
        #if no match or end of string,return
        return

checkMatch(string,pattern,hashp)

代码工作得很好。我的问题是这是一种有效的方法吗?可能存在逻辑可能失败的任何实例吗?我遇到的所有Rabin Karp算法都没有使用这个逻辑代替每一场比赛,它进一步逐字逐句检查,以确保它不是一个字谜。如果我这样做,那是不是错了?我的观点是,只要哈希值匹配,就会使用此代码,您无需逐个字符地逐一检查字符串,您可以继续查看下一个字符串。

1 个答案:

答案 0 :(得分:1)

没有必要只有anagrams与模式的哈希值冲突。具有相同散列值的任何其他字符串也可能发生冲突。相同的哈希值可以充当骗子,因此需要逐个字符匹配。

例如在你的情况下,你正在采用mod 100.采用任何不同的101模式,然后通过Pigeonhole原则,其中至少有两个将具有相同的哈希值。如果您使用其中一个作为模式,那么如果您避免字符匹配,则其他字符串的存在会使您的输出出错。

此外,即使使用了您使用的哈希,两个字谜也可以具有相同的哈希值,这可以通过求解两个线性方程来获得。 例如,

DCE = 4*1 + 3*2 + 5*3 = 25
CED = 3*1 + 5*2 + 4*3 = 25