过去学习算法的过程一直是断断续续,效果与最初期望的相差甚远,很多常用的基础内容遗忘殆尽。在这个承上启下的学期,始终觉得巩固好基础尤为重要。
Here comes the question,模式匹配是啥子哇?———— 在一个较长字符串t中查找和一个较短字符串p完全相同的子串的过程。这边的p被称为模式,t自然是目标串。
朴素匹配的思想是用两个指针分别依次指向目标串和模式串的一个字符,目标串从其第一个字符开始和模式串的第一个字符进行比较,如果目标串当前指向的字符和模式串第一个字符不等,则目标串指针后移,用模式串第一个字符与之继续,如果目标串中当前字符和模式串第一个字符开始匹配,则两指针依次后移挨个匹配,出现对应字符不等的情况则目标串指针回退,回退的字符数是模式串指针移动的次数(出现回溯),再继续让目标串当前字符和模式串第一个字符比较,依次类推,直到匹配成功完整的子串。
实际编码过程中,定义两个整型变量j,i分别记录目标串和模式串当前指向的字符,函数体的主要部分就是扫一遍目标串,扫描完后检查i是否能够达到p串长度的值,算法复杂度O(len_p*len_t),详细代码用C实现了一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 在目标串中找到模式串,则返回模式串首字符在目标串的位置(下标+1),
//找不到返回-1
int match(char* t,char*p,int len_t,int len_p){
int i,j; // i记录p当前字符下标,j记录t当前字符下标
i=0;j=0; // initialize
while(i<len_p && j<len_t){
if(t[j]==p[i]){ // 如果匹配成功,继续依次向后匹配
++j;
++i;
}else{ // 如果当前匹配失败
j = j-i+1; // j退到上次开始匹配p[0]的字符的下一个字符(回溯)
i=0; // i指向p[0],准备下次重新匹配
}
}
if (i>=len_p) return j-len_p+1; // 如果匹配成功,注意这边+1
else return -1; // 匹配失败
}
算法比较简单,详细思路见注释。