字符串相似性:Bitap究竟是如何工作的?

时间:2012-07-03 19:38:03

标签: algorithm bit-manipulation similarity

我正试图绕过Bitap算法,但我无法理解算法步骤背后的原因。

我理解算法的基本前提,即(如果我错了,请纠正我):

Two strings:     PATTERN (the desired string)
                 TEXT (the String to be perused for the presence of PATTERN)

Two indices:     i (currently processing index in PATTERN), 1 <= i < PATTERN.SIZE
                 j (arbitrary index in TEXT)

Match state S(x): S(PATTERN(i)) = S(PATTERN(i-1)) && PATTERN[i] == TEXT[j], S(0) = 1

在英语术语中,如果前一个子串PATTERN.substring(0,i)成功匹配且PATTERN.substring(0, i-1)处的字符与PATTERN[i]处的字符相同,则TEXT[j]匹配TEXT的子字符串

我不明白的是这个位移实现。 The official paper detailing this algorithm basically lays it out,但我似乎无法想象应该继续发生什么。 算法规范只是论文的前两页,但我将重点介绍重要部分:

以下是该概念的位移版本:

enter image description here

以下是样本搜索字符串的T [text]:

enter image description here

这是一个算法的痕迹。

enter image description here

具体来说,我不明白T表的含义,以及OR当前状态中的条目背后的原因。

如果有人能帮我理解究竟发生了什么,我将不胜感激

2 个答案:

答案 0 :(得分:14)

T有点令人困惑,因为你通常在数字中排名 从左到右的模式:

0 1 2 3 4
a b a b c

...而位通常从右到左编号。

但写作 位于位上方的模式清楚地说明了:

  bit: 4 3 2 1 0

       c b a b a
T[a] = 1 1 0 1 0

       c b a b a
T[b] = 1 0 1 0 1

       c b a b a
T[c] = 0 1 1 1 1

       c b a b a
T[d] = 1 1 1 1 1
如果T[x]出现在 n 的位置,则<{1>} 0的位 n x,如果是1则为x没有。

同样地,你可以认为这是说当前的角色 在输入字符串中0,您在T[x] n 位置看到0,然后您 如果匹配开始 n 字符,则只能匹配模式 先前。


现在进行匹配程序。状态位 n 中的 [start] 1 1 1 1 1 表示我们开始匹配模式 n 字符前(其中0是当前字符)。最初,没有任何匹配。

a

当我们消耗试图匹配的字符时,状态向左移动(向内移动零 到最后一位,位0)和OR-ed与当前字符的表项。第一个字符是T[a];左移和 a 1 1 1 1 0 中的OR-ing给出:

0

保留了移入的a位,因为1的当前字符可以 开始匹配模式。对于任何其他字符,该位将被设置为 0

状态的第0位现在是 a b 1 1 1 0 1 ,这意味着我们开始匹配模式 当前的性格;继续,我们得到:

0

...因为T[b]位已向左移位 - 想到它说我们开始匹配1个字符前的模式 - 而0同时有b位置,告诉 我们如果我们开始匹配1个字符,那么在当前位置看到 a b d 1 1 1 1 1 是好的 前。

d

1无法在任何地方匹配;所有位都设置回 a b d a 1 1 1 1 0

a b d a b
1 1 1 0 1

和以前一样。

b d a b a
1 1 0 1 0

和以前一样。

a
如果匹配在2个字符之前或在当前字符上开始,则

d a b a b 1 0 1 0 1 是好的。

b
如果匹配在1或3个字符之前开始,则

0是好的。位3中的a b a b a 1 1 0 1 0 表示 我们几乎完全符合整个模式...

a

...但是下一个字符是b a b a b 1 0 1 0 1 ,如果匹配开始4个字符,那就不好了 前。但是,较短的匹配可能仍然很好。

a b a b c
0 1 1 1 1

看起来还不错。

c

最后,如果匹配在之前的4个字符开始,则0 。这个事实 {{1}}已经一直到最高位意味着我们有匹配。

答案 1 :(得分:0)

很抱歉不允许其他人回答,但我很确定我现在已经知道了。

对算法进行挖掘所必需的概念是以二进制表示匹配状态(在原始帖子中定义)。原帖中的文章正式解释了它;我会亲自尝试这样做:

我们有STR,这是一个用给定字母表中的字符创建的字符串。

让我们用一组二进制数字代表STRSTR_BINARY。该算法要求此表示向后(因此,第一个字母对应于最后一个数字,第二个字母对应倒数第二个数字等)。

我们假设RANDOM引用了一个字符串,其中包含来自同一字母STR的随机字符。

STR_BINARY中,给定索引处的0表示RANDOMSTR中的STR[0]匹配

STR[(index of letter in STR that the 0 in STR_BINARY corresponds to)]。空格数计为匹配项。 1表示RANDOM与这些相同边界内的STR不匹配。

一旦理解了算法,该算法就变得更容易学习了。