#笔记整理
若不了解串的定义,可至:
串(string)的定义与表示 查看
串的模式匹配算法
求子串位置的定位函数 Index(S, P, pos)
求子串的定位操作通常称作串的模式匹配(其中子串P称为模式串)。
算法1:朴素模式匹配算法/简单匹配算法(Brute-Force算法,简称BF算法)
从目标主串 s = “ s 1 s 2 … s n ” s=“s_1s_2…s_n” s=“s1s2…sn”的第一个字符开始和模式串 p = “ p 1 p 2 … p m ” p=“p_1p_2…p_m” p=“p1p2…pm”中的第一个字符比较,若相等,则继续逐个比较后续字符;否则从目标主串s的第二个字符开始重新与模式串p的第一个字符进行比较。依次类推,若从目标串s的第i个字符开始,每个字符依次和模式串p中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,函数返回0。
实现代码:
// ——————————串的定长顺序存储表示————————————————
#define MAXSTRLEN 255 //最大串长
typedef char SString[MAXSTRLEN+1];
// C语言实现
int index(SString s, SString t, int pos){
// t非空, 1 <= pos <= strlen(s)
int i = pos;
int j = 0;
int sLen = strlen(s);
int tLen = strlen(t);
while(i < sLen && j < tLen){
if(s[i] == t[j]){
i++;
j++;
}else{
i = i - j + 2;
j = 1;
}
}
if(j >= tLen){
return i - tLen;
}else{
return 0;
}
}
// C++实现
int index2(string s, string t, int pos){
// t非空, 1 <= pos <= Strlength(s)
int i = pos;
int j = 0;
int sLen = s.length();
int tLen = t.length();
while(i < sLen && j < tLen){
// s[0]、t[0]为串长度
if(s[i] == t[j]){
i++;
j++;
}else{
i = i - j + 2;
j = 1;
}
}
if(j >= tLen){
return i - tLen;
}else{
return 0;
}
}
源代码:github地址(其中有详细注释)
朴素模式匹配算法的时间复杂度分析
主串长n; 子串长m。可能匹配成功的位置(1 ~ n-m+1)。
- 最好的情况下,
第i个位置匹配成功,比较了(i - 1 + m)次,平均比较次数:
最好情况下算法的平均时间复杂度O(n+m)。 - 最坏的情况下,
第i个位置匹配成功,比较了(i * m)次,平均比较次数:
设 n >> m,最坏情况下的平均时间复杂度为O(n * m)。
算法2:朴素模式匹配算法的改进算法:KMP算法
KMP算法是 D.E.Knuth、J.H.Morris 和 V.R.Pratt 共同提出的,简称KMP算法。该算法较BF算法有较大改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。
当主串的第 i 个字符与子串的第 j 个字符失配时,若主串的第 i 个字符前的 ( k - 1 ) 个字符与子串的前 ( k -1 ) 个字符匹配,则只需主串的第 i 个字符与子串的第 k 个字符开始向后比较即可,i 不必回溯。
为此,定义 next[] 数组,表明当模式中第 j 个字符与主串中相应字符“失配”时,在模式串中需重新和主串中该字符进行比较的字符的位置 k,即 n e x t [ j ] = k next[j] = k next[j]=k。
实现代码:
// KMP,C语言实现
int indexKMP(SString s