如何实现C#中的KMP算法
KMP(Knuth-Morris-Pratt)算法,是一种高效的字符串匹配算法,用于在文本串中查找模式串的位置。它的核心思想是利用已匹配的部分信息,避免不必要的比较。
实现KMP算法的关键是构建一个部分匹配表(Partial Match Table),也叫做next数组。这个数组记录了模式串中每个前缀子串的最长可匹配后缀子串的长度。
下面是C#中实现KMP算法的具体步骤和代码示例:
步骤一:构建部分匹配表
- 定义一个大小为模式串长度的整型数组 next,并初始化 next[0] = -1。
- 定义两个指针 i 和 j,初始值分别为 0 和 -1。
- 判断 i 是否达到模式串的末尾,若没有则执行以下步骤:
a. 若 j 等于 -1 或者当前字符和指针 j 对应的字符相等,则 i 和 j 同时后移,并将 next[i] = j。
b. 否则,将指针 j 移动到 next[j] 的位置,继续进行匹配。 - 返回构建好的部分匹配表 next。
以下是如何实现上述步骤的代码:
private int[] BuildNext(string pattern)
{
int[] next = new int[pattern.Length];
next[0] = -1;
int i = 0, j = -1;
while (i < pattern.Length - 1)
{
if (j == -1 || pattern[i] == pattern[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
return next;
}
步骤二:使用部分匹配表进行匹配
- 定义两个指针 i 和 j,分别指向文本串和模式串的起始位置。
- 判断 i 和 j 是否达到末尾,若没有则执行以下步骤:
a. 若 j 等于 -1 或者当前字符和指针 j 对应的字符相等,则 i 和 j 同时后移。
b. 否则,将指针 j 移动到 next[j] 的位置,继续进行匹配。 - 若指针 j 指向模式串的末尾,表示匹配成功,返回起始位置在文本串中的索引。
- 若匹配失败,返回 -1。
以下是如何实现上述步骤的代码:
private int KMP(string text, string pattern)
{
int[] next = BuildNext(pattern);
int i = 0, j = 0;
while (i < text.Length && j < pattern.Length)
{
if (j == -1 || text[i] == pattern[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == pattern.Length)
{
return i - j;
}
return -1;
}
通过调用 KMP 方法,并传入文本串和模式串,即可获得匹配结果。