书中依次讲了4种方法,朴素算法、RabinKarp算法、有限自动机算法、KMP算法
1、朴素算法:
算法用一个循环来找出所有有效位移,该循环对n-m+1个可能的每一个s值检查条件P[1...m] = T[s+1....s+m];
//朴素的字符串匹配算法
void nativeStringMatcher(string st, string sp)
{
int n = st.length(); //主串长度
int m = sp.length(); //模式串长度
for (int s = 0; s <= n-m+1; s++)
{
string ss = st.substr(s, m); //ss为st从s位置开始的m个字符,即和sp比较的字符串
if (sp == ss)
cout << "在位置" << s << "处发现匹配" << endl;
}
}
上面函数调用了string比较是否相等的操作,如果不用这样比较,即一个字符一个字符比较,则有暴力枚举法如下:
int ViolentMatch(char* s, char* p)
{
int sLen = strlen(s);
int pLen = strlen(p);
int i = 0;
int j = 0;
while (i < sLen && j < pLen)
{
if (s[i] == p[j])
{
//①如果当前字符匹配成功(即S[i] == P[j]),则i++,j++
i++;
j++;
}
else
{
//②如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0 即j回到0,i回到i-j+1处重新比较,下面介绍的KMP算法的不同就在于i不会回到i-j+1,而j也不一定非要回到0比较
i = i - j + 1;
j = 0;
}
}
//匹配成功,返回模式串p在文本串s中的位置,否则返回-1
if (j == pLen)