在介绍KMP算法之前,首先先描述一下简单的字符串匹配算法BF算法。
1.BF算法
BF算法是普通的模式匹配算法,BF算法的思想就是将目标串M的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个字符和P的第二个字符;若不相等,则比较S的第二个字符和P的第一个字符,依次比较下去,直到得出最后的匹配结果。
C#代码:
public static int BFStringMatch(string p, string m)
{
int i = 0;
int j = 0;
int index = 0;
while (i < p.Length && j < m.Length)
{
if (p[i] == m[j])
{
i++;
j++;
}
else
{
index++;
j = index;
i = 0;
}
}
return j;
}2.KMP算法
kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是根据给定的模式串P定义一个next[]数组。
对于next[]数组的定义如下:
1) next[j] = -1 j = 0
2) next[j] = max(k): 0<k<j P[0...k-1]=P[j-k,j-1]
3) next[j] = 0 其他
例子:
P: a b a b c
j: 0 1 2 3 4
next[j]: -1 0 0 1 2
C# 代码:
public static int[] GetNext(string p)
{
int[] next = new int[p.Length];
for (int i = 0; i < p.Length; i++)
{
if (i == 0)
{
next[i] = -1;
}
else if (i == 1)
{
next[i] = 0;
}
else
{
int temp = i - 1;
for(int j=temp;j>0;j--)
{
if (IsStringMatch(p, j, i))
{
next[i] = j;
break;
}
if (j == 0)
next[i] = 0;
}
}
}
return next;
}
public static bool IsStringMatch(string p, int j, int i)
{
bool resulte = true;
for (int n = 0, s = i - j; n < j && s < i; n++, s++)
{
if (p[n] != p[s])
{
resulte = false;
}
}
return resulte;
}
获得next[]之后,KMP算法中最核心的部分就完成。现在进行字符串的匹配。其基本思想是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串M的指针i不变,将模式串P的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。
C# 代码
public static int KMPStringMatch(string p,string m)
{
int[] next = GetNext(p);
int i = 0;
int j = 0;
while (i < m.Length&&j<p.Length)
{
if (m[i] == p[j])
{
i++;
j++;
}
else if (next[j] == -1)
{
i++;
j = 0;
}
else
{
j = next[j];
}
Console.WriteLine(j);
}
if (j == p.Length )
{
return i - p.Length;
}
else
{
return -1;
}
}
162

被折叠的 条评论
为什么被折叠?



