* 什么是朴素模式?
朴素模式思路:从主串的第一位开始与要匹配的字符串的第一位做对比,若相同,比较下一位,若不同,从主串的第二位开始与要匹配的字符串的第一位做对比,以此类推。
例:主字符串 M 为 ababcdx,要匹配的字符串 T 为 abx。
第一次:M[0] == T[0], M[1] == T[1], M[2] != T[2], 第一次匹配失败。
第二次:M[1] != T[0], 第二次匹配失败。
第三次:M[2] == T[0], M[3] == T[1], M[4] != T[2], 第三次匹配失败。
第四次:M[3] != T[0], 第四次匹配失败。
第五次:M[4] != T[0], 第五次匹配失败。
第六次:主字符串未匹配字符只剩2个,匹配彻底失败。
代码如下:
int Index(char* M, char* T, int Mlength, int Tlength)
{
int i = 0, j = 0;
while (i < Mlength && j < Tlength) //当i小于M长度,j小于T的长度时循环
{
if (M[i] == T[j]) //若一个字符匹配,则匹配下一个字符
{
i++;
j++;
}
else //若不匹配,则i回到上次匹配首位的下一位,j回第0位
{
i = i - j + 1;
j = 0;
}
}
if (j >= Tlength)
return i - Tlength;
else
return 0;
}
* 什么是KMP模式?
在朴素模式中,有重复遍历的情况出现,使用KMP模式可以避免这些情况。
void get_next(char* T, int Tlength, int* next)
{
int i = 2, j = 1;
next[1] = 0;
next[2] = 1;
while (i < Tlength)
{
if (j == 0 || T[i - 1] == T[j - 1])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
}
int index_KMP(char* M, char* T, int Mlength, int Tlength)
{
int i = 0, j = 0;
int* next = (int*)malloc((Tlength + 1) * sizeof(int));
get_next(T, Tlength, next);
while (i < Mlength && j < Tlength)
{
if (M[i] == T[j])
{
i++;
j++;
}
else
j = next[j + 1] - 1;
}
if (j >= Tlength)
return i - Tlength;
else
return 0;
}
朴素模式算法的改进:
void get_nextval(char* T, int Tlength, int* nextval)
{
int i = 2, j = 1;
nextval[1] = 0;
nextval[2] = 1;
while (i < Tlength)
{
if (j == 0 || T[i - 1] == T[j - 1])
{
i++;
j++;
if (T[i - 1] != T[j - 1])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}
int index_KMP(char* M, char* T, int Mlength, int Tlength)
{
int i = 0, j = 0;
int* next = (int*)malloc((Tlength + 1) * sizeof(int));
get_nextval(T, Tlength, next);
while (i < Mlength && j < Tlength)
{
if (M[i] == T[j])
{
i++;
j++;
}
else
j = next[j + 1] - 1;
}
if (j >= Tlength)
return i - Tlength;
else
return 0;
}