字符串的模式匹配
来源:互联网 发布:德国狂屠巴西 知乎 编辑:程序博客网 时间:2024/05/16 16:08
字符串的模式匹配是数据结构中很重要的一部分内容,它是字符串的一个应用。记得当时吴暇老师给我们将数据结构的时候多次强调的,已经还给老师多年,今天来review下。
所谓模式匹配是这个意思:有两个字符串,such as “abbcabd" n ”bca”。求bca是不是abbcabd的子串,如果是就返回在abbcabd中出现的bca的下标值。在这个demo中是2。那么abbcabd叫作目标串(subject),bca叫模式串(pattern)
模式匹配一个直观的算法就是逐个进行匹配检验。也就是从目标串的第0个元素开始和模式串的第0个元素进行比较。如果相等,再从模式串的第1个元素和目标串的第1个元素进行比较。。。如果一旦不相等,就回退回去。这里有一个BF算法。实现如下:
int BFMatch(std::string subject, std::string pattern) { if(subject.size()<pattern.size()) return -1; int i=0,j=0; while(i<subject.size() && j<pattern.size()){ if(subject.at(i)==pattern.at(j)){ i++; j++; }else{//元素不相等的时候 i=i-j+1;//指针回溯到进行匹配的位置 j=0;//模式串从回到第0位置再进行下一次的匹配 } } if(j>=pattern.size()) return i-pattern.size(); return -1; }BF的时间复杂度最好的情况下是O(m),最坏的情况下是O(n*m),其中m是模式串的长度,n是目标串的长度。
对BF算法进行优化,就有了大名鼎鼎的KMP算法。KMP利用了模式串本身的对称性,在进行匹配失败的时候,i指针不用进行回溯。而是根据 j的在next数组中的值进行处理。
如果next[j]==-1:i和j都指向下一个字符;
如果next[j]==k(k!=-1):j不用从0开始,而是从模式串上的第k个位置开始,在进行匹配
所以在BF算法的基础上只要进行一点点的改动就有了KMP下的模式匹配,实现如下:
int KMPMatch(std::string subject, std::string pattern) { if(subject.size()<pattern.size()) return -1; next(std::string pattern, next);//next数组通过这个方法已经得到 int i=0,j=0; while(i<subject.size() && j<pattern.size()){ if(subject.at(i)==pattern.at(j)){ i++; j++; }else{//元素不相等的时候 j=next[j];//模式串从回到第next[j]位置再进行下一次的匹配 } } if(j>=pattern.size()) return i-pattern.size(); return -1; }so,剩下的问题就是怎么计算next数组。next数组的计算可以说是KMP算法最最精彩的部分,当时学的时候也是很confuse,后来终于是理解了。next数组有多重计算方法,得出的值也是不尽相同,现在展示两种教程上的。分别记为next和nextVal,后者是前者的改进。代码如下:
void getNextArray(char pattern[], int next[]) { if (pattern==NULL) return; int j=0,k=-1; next[0] = -1; while(pattern[j]!='\0'){ if(k==-1 || pattern[j]==pattern[k]){ next[++j] = ++k; }else{ k = next[k]; } } return;}
void getNextArrayAdvanced(char pattern[], int next[]) { if (pattern==NULL) return; int j=0,k=-1; next[0] = -1; while(pattern[j]!='\0'){ if(k==-1 || pattern[j]==pattern[k]){ if(pattern[++j]!=pattern[++k]){ next[j] = k; }else{ next[j]=next[k]; } }else{ k = next[k]; } } return;}anyway,详细的内容可以参考我们的教科书:李春葆的《数据结构教程》第二版,以及这两个blog,我觉得写的很清晰推荐下:
http://www.cppblog.com/oosky/archive/2006/07/06/9486.html
http://www.cnblogs.com/yjiyjige/p/3263858.html
0 0
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的简单模式匹配
- 简单的字符串模式匹配
- 回溯的字符串模式匹配
- 字符串的多模式匹配
- 字符串的模式匹配KMP
- 字符串的模式匹配问题
- 字符串的模式匹配方法
- KMP字符串模式匹配的C实现
- 字符串的模式匹配算法 KMP
- 字符串的模式匹配(回溯法)
- 两个字符串模式匹配的算法
- iOS中的类的标准格式
- 学习笔记(九)内容提供器
- VNC/Servers(总结)
- 12期 5月期刊自荐
- C++中多字节与双字节的字符的转换
- 字符串的模式匹配
- 判断是否为闰年
- ♥NYOJ 123-士兵杀敌(四)【线段树&&树状数组】
- CArchive类基本读写
- C# 小伎俩给PDF添加图片背景
- 最小生成树(二)--prim算法实现以及堆优化
- Spring——基于注解方式的依赖注入
- lightoj 1045(数论)
- uva 11008 Antimatter Ray Clearcutting 记忆化搜索