一、BF算法
BF算法是模式匹配算法的一种穷举的,经典的算法。
子串会从主串第一位开始进行挨个的匹配,若发现一一对应匹配不成功,主串往后移动一位,子串又从第一位开始进行匹配,如此往复进行,这就是BF算法。
代码中,while的循环条件在不超过主子串的长度下进行,因为超过的话就表示不符合要求也没必要进行了。然后一一进行数据的校对,如果相同则校对下一位(i++,j++),如果校对不一样,则主串需要返回到上一次初始移动的下一位,子串则回到第一位重新开始。这里j=1不用解释,i的回溯的话,每次i的移动j也会随之移动一位,则i减去j等于包括i初始移动位置全部减去了,此时加1回到原本的初始位置,再加1便是下一个需要移动到的位置,因此是i-j+2。
判断校对的方式,子串移动数j超过子串本身长度说明校对相同,匹配正确,返回值为主串当前移动位i减去子串长度T.length即是主串与子串对应位置的初始处。
int BF_algorithm(SString S, SString T)//S主串,T子串
{
int i = 1, j = 1;
while (i <= S.length && j <= T.length)
{
if (S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
{
i = i - j + 2;
j = 1;
}
}
if (j > T.length)return i - T.length;
else return 0;
}
二、KMP算法(不太了解)
KMP算法相较于上面的BF算法来说不需要重复大量的回溯来进行校对,通过next数组可以进行高效的匹配,极大地提高了运行的效率,但相对也较难理解。主要是next数组理解起来需要一段时间。
KMP算法代码如下,其中GetNext函数为next数组部分,下面的函数其实和BF算法的一样,只不过i和j的回溯发生了改变,主串不需要进行回溯,而子串则回溯到next数组给定位置。
//串的模式匹配算法--KMP算法
//next数组
#define MaxSize 100
typedef struct{
char data[MaxSize+1];
int length;
} SqString;
void GetNext(SqString t, int next[])
{
int j, k;
j = 1; k = 0;
next[1] = 0;
while (j < t.length - 1)
{
if (k == 0 || t.data[j] == t.data[k])
{
j++; k++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int KMPIndex(SqString s, SqString t) //KMP算法
{
int next[MaxSize], i = 0, j = 0;
GetNext(t, next);//next数组
while (i < s.length && j < t.length)
{
if (j == 0 || s.data[i] == t.data[j])
{
i++; j++;
}
else j = next[j];
}
if (j >= t.length)return(i - t.length);
else return 0;
}