2.4、字符串模式匹配
资讯网址:www.qghkt.com
腾讯课堂:https://qghkt.ke.qq.com/20个常用算法
模式串(或子串)在主串中的定位操作通常称为串的模式匹配,它是各种串处理系统中最重要的运算之一。
2.4.1、布鲁特-福斯算法
【基本思想】
从主串的第一个字符起与模式串的第一个字符比较,若相等,则继续逐个字符进行后续比较,否则从主串的第二个字符起与模式串的第一个字符重新开始比较,直至模式串中每个字符依次与主串中的一个连续的字符序列相等时为止,此时称为匹配成功;如果在主串中不存在与模式串相同的子串,则匹配失败。
【图解过程】
给定主串“ABCDABCDABBABCDABCDABDD”,子串“ABCDABD”。
1)第一趟比较,先比较A,然后是BCDAB。
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
B |
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
D |
D |
A |
B |
C |
D |
A |
B |
在比较最后一个字符D时,不匹配。
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
B |
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
D |
D |
A |
B |
C |
D |
A |
B |
D |
2)第二趟比较,主串回退到比前一趟加1的位置。子串从0开始。第一个就不匹配。结束本趟。
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
B |
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
D |
D |
A |
3)第三趟比较,主串前移一个位置,子串从0开始。第一个还是不匹配。同样结束本趟。
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
B |
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
D |
D |
A |
……
i)第i趟比较,找到可以匹配的子串
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
B |
A |
B |
C |
D |
A |
B |
C |
D |
A |
B |
D |
D |
A |
B |
C |
D |
A |
B |
D |
【查找长度】
假设主串的长度为n,模式串的长度为m,位置序号从1开始。设从主串的第i个字符位置开始与模式串匹配成功,而在前i-1趟匹配中,每趟不成功的匹配都是模式串的第一个字符与主串中相应的字符不相同,则在前i-1趟匹配中,字符间的比较共进行了i-1次,因第i趟成功匹配的字符比较次数为m,所以总的字符比较次数为i-1+m且1≤i≤n-m+1。若在这n-m+1个起始位置上匹配成功的概率相同,则在最好的情况下,匹配成功时字符间的平均比较次数为。最好的情况下为O(n+m)。最坏的情况下,每一趟不成功的匹配都是模式串的最后一个字符与主串中相应的字符不相等。若设第i趟匹配时成功,则前i-1趟不成功的匹配中,每趟都比较了m次,总共比较了(i-1)*m+m,平均比较次数为。由于,所以该算法在最坏情况下的时间复杂度为O(n*m)。
【算法代码】
/****************************************************************
* 函数名称:searchFS
* 功能描述:布鲁特-福斯模式匹配
* 参数说明:src, 主串
* sub, 模式串
* 返 回 值:-1,表示不成功,非0的值表示模式串sub在主串src的位置
* 作 者:www.qghkt.com
* 创建时间:
*****************************************************************
* Copyright @ 清哥好课堂 Allrights reserved
*****************************************************************/
int searchFS(const char *src, const char*sub)
{
int i, j;
i = 0;
j = 0;
int strLen= strlen1(src);
int tLen =strlen1(sub);
while(i<strLen && j<tLen)
{
if(src[i] == sub[j])
{
++i;
++j;
}
else
{
//主串回退
i= i - j + 1;
//子串
j= 0;
}
}
if (j>= tLen)
{
return(i - tLen);
}
return -1;
}
int searchFS(const char *src, const char*sub, int pos)
{
int i, j;
i = pos;
j = 0;
int strLen= strlen1(src);
int tLen =strlen1(sub);
while(i<strLen && j<tLen)
{
if (src[i]== sub[j])
{
++i;
++j;
}
else
{
//主串回退
i= i - j + 1;
//子串
j= 0;
}
}
if (j>= tLen)
{
return(i - tLen);
}
return -1;
}
/****************************************************************
* 函数名称:searchFSAll
* 功能描述:查找模式串在主串中所有的出现的位置
* 参数说明:locArr, 位置的数组
* src, 主串
* sub, 模式串
* 返 回 值:0,表示没有匹配的,非值,表示有匹配的个数
* 作 者:www.qghkt.com
* 创建时间:
*****************************************************************
* Copyright @ 清哥好课堂 Allrights reserved
*****************************************************************/
原文地址:https://www.cnblogs.com/lifecode/p/9314264.html