KMP DFA 重启状态
Posted
技术标签:
【中文标题】KMP DFA 重启状态【英文标题】:KMP DFA restart state 【发布时间】:2020-07-12 17:41:22 【问题描述】:我指的是“Sedgewick & Wyane 的算法第四版”字符串匹配第 5 章。
给定的算法是 KMP 子字符串搜索,它从模式状态构建 DFA。我了解构建 DFA 的算法,代码如下:
public KMP(String pat)
this.R = 256;
this.pat = pat;
// build DFA from pattern
int m = pat.length();
dfa = new int[R][m];
dfa[pat.charAt(0)][0] = 1;
for (int x = 0, j = 1; j < m; j++)
for (int c = 0; c < R; c++)
dfa[c][j] = dfa[c][x]; // Copy mismatch cases.
dfa[pat.charAt(j)][j] = j+1; // Set match case.
x = dfa[pat.charAt(j)][x]; // Update restart state.
我无法获得以下行:x = dfa[pat.charAt(j)][x]; // Update restart state.
我知道这个值是通过在部分构建 DFA 中提供 pat[1..j-1] 来实现的,但无法获得该代码,它是如何实现的。
我也明白 x 是模式的最长前缀的长度,也是后缀。
我看过许多其他相关问题,但这些问题与理解算法本身有关。
我需要了解x = dfa[pat.charAt(j)][x]; // Update restart state.
如何模拟重启状态。
【问题讨论】:
【参考方案1】:如果我们仔细看,X 被初始化为状态 0,J 被初始化为状态 1
现在,我们只是根据访问的下一个字符继续向前移动,并且由于 X 在 J 后面,他已经知道下一个状态,默认情况下 ALL ARE POINTING BACK TO 0 因此该行将始终保持前缀,否则在 0 处重新启动
dfa[c][j] = dfa[c][x]; // Copy mismatch cases.
此行只是创建failure
或back pointers
x = dfa[pat.charAt(j)][x]; // Update restart state.
并且这条线将前缀向前移动,与 J 保持同步,所以它总是指向前缀 == 后缀的地方
也许这将有助于进一步https://labuladong.gitbook.io/algo-en/i.-dynamic-programming/kmpcharactermatchingalgorithmindynamicprogramming
【讨论】:
【参考方案2】:首先你应该知道X的含义:
在我们更新它之前,这意味着我们将从当前状态(匹配的j个字符)到的状态(成功匹配多少个字符) 更新后的状态表示从下一个状态(j + 1个匹配的字符)进入的状态然后
X的更新是由txt[i]和pat[j]匹配成功引起的,注意,他们需要什么状态才能匹配成功 (状态决定x,这里需要的字符决定了x = dfa[pat.charAt(j)][x])的pat.charAt(j),在第一次匹配失败的状态,状态成为原点X,因为我们需要在search()的下一个循环中匹配txt[i + 1]而不是txt[i]
【讨论】:
以上是关于KMP DFA 重启状态的主要内容,如果未能解决你的问题,请参考以下文章