KMP进阶版 (状态机思想)
思想升华:KMP本质是状态机,而状态机可以处理流数据
int GetNext(int *j, char input) {
while (*j && t[*j + 1] != input) *j = next[*j];
if (t[*j + 1] == input) ++*j;
return *j;
}
void KMP() {
int n = strlen(t + 1);
for (int i = 2, j = 0; t[i]; ++i) next[i] = GetNext(&j, t[i]);
for (int i = 1, j = 0; s[i]; ++i) {
GetNext(&j, s[i]);
if (j == n) {
Index[++t_ind] = i - n + 1;
j = next[j];
// 13、14行是把文本串中所有能完全匹配上模式串的子串全部保存下来
}
}
return ;
}
其中:s
为文本串, t
为模式串 ,数据都是从下标 1
位置开始存储
其实无论是 next
数组的计算,还是文本串和模式串匹配的过程。抽象出来都是拿一个元素出来,去尝试改变 j
的状态
这恰好就是状态机的思想,状态机就是状态转移图
关于状态机的一个极度确切的描述是:它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。
—— 百度百科
所以抽象成状态机,核心代码即 GetNext
函数,可以统一KMP算法中计算 next
数组和 文本串匹配的过程。j
是和模式串t
关联的,无论函数传入的是模式串的元素,还是文本串的元素,都是为了改变j
的状态。
KMP 多画,多思考