KMP算法在字符串方面有着广泛的应用,敏感词过滤,分词等。
使用C#实现了一把,作为备忘。
i指针回溯的算法为:
代码
public
int
Index(
string
s,
string
t)
{
int i = 0 ,j = 0 ;
while (i < s.Length && j < t.Length)
{
if (j == 0 || s[i] == t[j])
{
i ++ ;
j ++ ;
}
else
{
i = i - j + 1 ; // i指针在此处回溯
j = 0 ;
}
}
if (j >= t.Length) return i - j;
else
return - 1 ;
}
{
int i = 0 ,j = 0 ;
while (i < s.Length && j < t.Length)
{
if (j == 0 || s[i] == t[j])
{
i ++ ;
j ++ ;
}
else
{
i = i - j + 1 ; // i指针在此处回溯
j = 0 ;
}
}
if (j >= t.Length) return i - j;
else
return - 1 ;
}
KMP算法就是字符串i指针不回溯,跟模式串指针j处的字符再比较。难点就是求Next值(构造失败指针),即从已匹配的“部分匹配”中找出一个最大的子匹配模式串。
数学公式为:S[0,k-1]== S[i- k, i-1]
KMP求Next
private
int
[] GetNext(
string
t)
{
int len = t.Length;
int [] next = new int [len];
int i = 1 ,j = 0 ;
while (i < len - 1 )
{
if (j == 0 || t[i] == t[j])
{
i ++ ;
j ++ ;
next[i] = j;
}
else
j = next[j];
}
return next;
}
{
int len = t.Length;
int [] next = new int [len];
int i = 1 ,j = 0 ;
while (i < len - 1 )
{
if (j == 0 || t[i] == t[j])
{
i ++ ;
j ++ ;
next[i] = j;
}
else
j = next[j];
}
return next;
}
KMP算法:
KMP
public
int
KmpIndex(
string
s,
string
t)
{
int i = 0 , j = 0 ;
int [] next = GetNext(t);
while (i < s.Length && j < t.Length)
{
if (j == 0 || s[i] == t[j])
{
i ++ ;
j ++ ;
}
else
j = next[j];
}
if (j >= t.Length) return i - j;
else
return - 1 ;
}
{
int i = 0 , j = 0 ;
int [] next = GetNext(t);
while (i < s.Length && j < t.Length)
{
if (j == 0 || s[i] == t[j])
{
i ++ ;
j ++ ;
}
else
j = next[j];
}
if (j >= t.Length) return i - j;
else
return - 1 ;
}