转贴
字符串匹配的KMP算法
编程新手烦恼了很久,自从看了这个帖子,终于想明白了KMP算法,代码是自己写的,比较菜,总的来说很开心!!!
using System;
namespace KMP01
{
class KMP {
private int[] matchTheValue;
/// <summary>
/// 通过前缀和后缀获取对应的关键字匹配值表
/// </summary>
/// <param name="keyword">关键字</param>
private void AcquireValue(string keyword) {
//关键字长度
int keywordLeg = keyword.Length;
//给匹配值表开辟空间
matchTheValue = new int[keywordLeg];
//i为matchTheValue的索引值
for (int i = 0; i < keywordLeg; i++) {
//j子关键字的长度
int j = i + 1;
//子关键字
string keywordChild = keyword.Substring(0, j);
//子关键字长度
int keywordChildLeg = keywordChild.Length;
//匹配子关键字的前缀和后缀
for (int l = keywordChildLeg - 1; l > 0; l--) {
//从长度最大的开始匹配前缀和后缀是否相同
if (keywordChild.Substring(0, l) == keywordChild.Substring(keywordChildLeg - l, l)) {
//将匹配的长度赋值给匹配值表
matchTheValue[i] = l;
break;
}
}
}
}
/// <summary>
/// KMP字符串匹配
/// </summary>
/// <param name="requireMatch">待匹配的字符串</param>
/// <param name="keyword">关键字</param>
/// <returns>如果匹配成功返回true,否则返回false</returns>
public bool Kmp(string requireMatch,string keyword) {
char[] requireMatchChar = requireMatch.ToCharArray();
char[] keywordChar = keyword.ToCharArray();
int requireMatchLeg = requireMatch.Length;
int keywordLeg = keyword.Length;
//先获取kmp匹配值表
AcquireValue(keyword);
for (int i = 0; i < requireMatchLeg; i++) {
int next = i;
for (int j = 0; j < keywordLeg; j++) {
if (requireMatchChar[next] != keywordChar[j]) {
if (j!=0) i += keywordLeg - matchTheValue[j - 1] - 2;
break;
}
if (requireMatchChar[next]==keywordChar[j]) {
if (j == keywordLeg - 1) return true;
else next++;
}
}
}
return false;
}
}
class Program
{
static void Main(string[] args)
{
KMP kMP = new KMP();
Console.WriteLine(kMP.Kmp("kmp真有趣", "kmp"));
Console.ReadKey();
}
}
}