[数据结构]字符串匹配算法
字符串匹配算法,指在字符串S中,寻找与匹配字符串T相等的子串,如果存在子串,则返回第一个子串的位置,如果不存在子串,则返回-1.
普通实现方法
思路:从字符串S的起始位置开始做比较,如果子串和字符串T不相等则向后移动一位,继续比较,直到找到相等的子串,或者已经查找了所有子串。
代码:
 View Code
View Code 
/// <summary>
/// find the index of string T in string S
/// </summary>
/// <param name="S"></param>
/// <param name="T"></param>
/// <returns>if found, return index, else return -1</returns>
public static int GetIndex(string S, string T)
{
int i = 0, j = 0, NotFound = -1, sLen = S.Length, tLen = T.Length;
if (sLen < tLen)
return NotFound;
while (i < sLen && j < tLen)
{
if (S[i] == T[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j == tLen)
return i - tLen;
else
return NotFound;
}
KMP实现方法
思路:从字符串S的起始位置开始做比较,当比较结果为不相等时,假设S的当前位置为i,T的当前位置为j,检查是否存在一个最大值k,满足0<=k<j-1,并且T0Tk与Tj-k-1Tj-1这两个子串相等。
如果k不存在,那么同普通实现方法。
如果k存在,此时T0Tk=Tj-k-1Tj-1,而且从之前的比较结果我们可以得知Tj-k-1Tj-1=Si-k-1Si-1,所以可以断定T0Tk=Si-k-1Si-1,所以此时我们不必重新比较T0Tk和Si-k-1Si-1这两个子串,而是比较Si-1和Tk之后的字符是否相等,即i不回退,j回退到k+1,然后继续比较。
现在的问题,转变为如何求这个k,由定义可知,当j=0的时候,k肯定不存在,next[0]=-1,
我们假设next[j]=k,由此可知T0Tk=Tj-k-1Tj-1,
如果Tk+1=Tj,那么可推得T0Tk+1=Tj-k-1Tj,即next[j+1]=k+1;
如果Tk+1!=Tj,那么继续比较Tj和Tnext[k+1],如果依然不相等,继续比较Tj和Tnext[next[k+1]],直至Tj与Tn相等,那么next[j+1]=next[n],或者不存在k
代码:
 View Code
View Code 
public static int GetIndexKMP(string S, string T)
{
int i = 0, j = 0, NotFound = -1, sLen = S.Length, tLen = T.Length;
int[] next = GetNextVal(T);
if (sLen < tLen)
return NotFound;
while (i < sLen && j < tLen)
{
if (j == -1 || S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == tLen)
return i - tLen;
else
return NotFound;
}
/// <summary>
/// get the next value array of a string T
/// </summary>
/// <param name="T"></param>
/// <returns></returns>
public static int[] GetNextVal(string T)
{
int i = 0, j = -1, tLen = T.Length;
int[] next = new int[tLen];
next[0] = -1;
while (i < tLen - 1)
{
if (j == -1 || T[i] == T[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
return next;
}
 
                    
                 
        
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号