博客仅做记录博主学习总结之用。

 

串是一种重要的数据结构,当需要从主串中寻找到目标子串时,在大学本科的《数据结构》中给出了两种算法

1、简单模式匹配算法

2、KMP算法

模式匹配:对一个串中某子串的定位操作称为串的模式匹配,待定位子串称为模式串。

 


对于串“ABGHHHCDGHHHIKK”,模式串“GHHHI”,简单模式匹配算法过程如下:

1、A-G,不匹配;B-G,不匹配;G-G匹配,H-H匹配,H-H匹配,H-H匹配,C-I不匹配;

---简单模式匹配算法开始会给三个变量i, j, k分别指向主串、模式串以及模式串和主串第一次匹配成功的位置(即G-G,因为变量k在匹配不成功时会移至下一位,所以如果匹配成功K一定停留在G-G)。

---当C-I不匹配时,i变量指向主串第k+1个变量即第一个G后面的第一个H,j变量指向模式串第一个字符G,k不变。

继续比较,会发现一直i在指向第二个G前,都不可能匹配成功,此时j不断地指向模式串第一个字符,k因为匹配不成功一直往后移位,i则一直跟随着k,直到k停下来。

---当来到第二个G时,G-G匹配,k停下来,i、j都自行++,(H-H)*3匹配,I-I匹配,至此匹配结束,此时变量i指向的是K,j指向模式串末尾。

简单模式匹配算法代码:(来自天勤2022数据结构)

 1 typedef struct{
 2       char* ch;
 3       int length;
 4 }Str;//结构体数组
 5 
 6 int _Match(Str str, Str substr)
 7 {
 8 
 9       int i, j, k;
10       i=1; j=1; k=i;
11       while(i<=str.length && j<=substr.length)
12     {
13           if(str.ch[i]==substr.ch[j])
14           {
15             ++i; ++j;
16            }
17           else
18           {
19             j=1; i=++k;
20           } 
21           if (j>substr.length)
22           return k;
23           else return 0;
24 
25     }

 

 


对于串“ABGHHHCDGHHHIKK”,模式串“GHHHI”,KMP算法过程如下:

在给出我对算法过程的理解分析之前,先说一下为什么要有这种算法吧(我瞎掰的)。KMP算法是为了改进简单模式匹配而生的,即对于短的串,人通过简单对比就能看出来“有没有”模式串的情况下,计算机反而用了比人更笨的方法,即简单模式匹配,而人则拥有强大的模糊算法,通过视觉和大脑的处理可以得到一个“好像有”,进而可进行一个快速定位。

计算机想要进行高效的定位(虽然看起来比较笨拙但还是比人快),则可以在此算法上进行一个改进,即对模式串中已经匹配成功的那部分串进行匹配,找出最长前后重合子串,然后再进行比较。这样我们需要一个next数组存放一下匹配失败后我们要从哪开始匹配的数据,匹配成功咱就不用这玩意了~

next数组:其含义是,要是在这一个字符我匹配失败了,那么指向模式串的变量,在下一步,应该指到哪去。

这个数组就存了这么个信息,好处是,主串不用回头,等模式串就好了。

在天勤里,为了解释他还给出了一个概念,名曰“状态”,其实就是i所指的位置匹配失败了,那么就得等到i所指的位置匹配成功时,才能继续比较主串后面的位置,此时原状态打破而进入新状态,也就说“进步了”能走到i后面的位置进行比较了,离真相进了一些(但是能不能找到是另一回事。)

注意一下这个“新状态”,它是指“匹配失败的地方某一刻匹配成功了,可以继续匹配后面了”,新状态不代表匹配的长度更长,仅仅代表匹配向后推进;当后面又匹配失败时,则又陷入了一个状态,当那个位置的字符再次被匹配成功得以进行那个字符位置之后的匹配,此时又进入新的状态。

嘤嘤嘤,不想写了,后面具体的过程和代码等我想写了再说。

 

posted on 2022-02-28 15:09  YUYOS_TWED  阅读(53)  评论(0)    收藏  举报