串匹配问题:

串模式匹配,简称串匹配,是数据结构中的经典问题,在邓俊辉版数据结构中,他的定义如下:

 对基于同一字符表的任何文本串T(|T| = n)和模式串P(|P| = m),判定T中是否存在某一子串与P相同,若存在(匹配),则报告该子串在T中的起始位置。

一般来说文本串T的长度n要远大于模式串P的长度m。到目前为止,有五花八门各种各样的串匹配算法,下面介绍一种最简单的蛮力算法。

蛮力算法(Brute Force)

在所有字符串匹配算法中,BF算法是最直接,最符合人直觉的算法,它只需要顺序地从文本串T中截取长度为m的子串t,再将这个子串和模式串P逐字母的比较就可以了。

选取子串

用两个指针i和j分别指向子串和模式串,比较对应的字符

如果对应的字符相等,如图,$t[i] = P[j]$,则i和j各自前进一位。

如果$t[i] \ne P[j]$,说明该子串和模式串不匹配

于是放弃该子串,在T中顺序选择下一个子串,重新开始上面的匹配过程。

当指向模式串P的指针j遍历完模式串后,说明所有的字符都匹配成功,那这个子串就找到了,返回这个位置就可以了。

字符串匹配的代码如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int BF(char*T,char*P)
 4 {
 5     int i,j;
 6     int m = strlen(P),n = strlen(T);
 7     printf("%d %d\n",m,n);
 8     i = j =0;
 9     while(j<m&&i<n)
10     {
11         if(P[j]==T[i])
12             i++,j++;
13         else
14         {
15             i = i-j+1;
16             j = 0;
17         }
18         if(j==m)
19             return i-j;
20     }
21     return -1;
22 }
23 int main()
24 {
25     char*T = "ABCDESABCDFAB";
26     char*P = "ABCDF";
27     int indexof = BF(T,P);
28     printf("%d\n",indexof);
29     return 0;
30 }

时间复杂度分析

 不难发现,文本串T至多有n-m+1个子串,每轮最多进行m次计较,所以最多需要比较$m*(n-m+1)$次,所以它的时间复杂度为$O(nm)$。最好的情况是每经一次比对就发现不匹配,这种情况下,BF算法的时间复杂度下降为$O(n)$,但是这种情况比较难出现。

 

BF算法虽然简单,但是在最坏情况下所需的时间,是文本串长度和字符串长度的乘积,当文本串很长时,它的时间复杂度会非常高,所以我们需要更加高效的算法。下一篇博客将介绍更高效的KMP算法。