我被要求了解KMP DFA,我在本书中发现的是实施,但我们的讲师一直称之为“前缀功能”。我真的无法理解这个功能在哪里,有人能解释一下吗?如果有人在某处问过我很抱歉,但我找不到它。
public class KMP {
private String pat;
private String t;
private int[][] fsm;
public static final int ALPHABET = 256;
public KMP(String pat) {
this.pat = pat;
char[] pattern = pat.toCharArray();
int M = pattern.length;
fsm = new int[ALPHABET][pattern.length];
fsm[pattern[0]][0] = 1;
for(int X = 0, j = 1; j < M; j++) {
for(int c = 0; c < ALPHABET; c++) {
fsm[c][j] = fsm[c][X];
}
fsm[pattern[j]][j] = j + 1;
X = fsm[pattern[j]][X];
}
display(fsm);
}
public void search(String t) {
char[] text = t.toCharArray();
this.t = t;
int N = text.length;
int M = pat.length();
int i, j;
for(i = 0, j = 0; i < N; i++) {
j = fsm[t.charAt(i)][j];
if(j == M) {
System.out.println("Found at " + (i - M + 1));
j = 0;
}
}
}
答案 0 :(得分:2)
KMP算法不构造DFA。您实现的内容看起来更像是DFA,它可识别某些字符串pattern
。
KMP算法背后的想法是为给定的pattern
构造所谓的前缀函数。这个功能是什么?它的定义是,对于字符串的每个位置i
,我们感兴趣的是pattern[1..i]
的最长后缀的长度,它也是pattern
字符串的前缀(0索引) 。这可能听起来令人困惑,但这是一个例子:
pattern = "abacabacada"
的前缀功能为pf[] = 0 0 1 0 1 2 3 4 5 0 1
。 pf[8]
等于5,因为“bacabaca”的最长后缀,也是“abacabacada”的前缀是“abaca”,其长度为5.类似地,pf[9] = 0
因为没有后缀bacabacad
的{{1}}也是abacabacada
的前缀(模式)。
我希望这个解释能使前缀功能更清晰。有些朋友调用数组,存储前缀函数fl
,“失败链接”的缩写,因为在进行匹配时,我们只在来自text
和{{1}的字符时才使用此数组中的值} mismatch。
Here是算法的明确实现(在Java中)。