sunday算法
2016-01-11 15:07
531 查看
前言:从看大话数据结构的KMP算法后深深的被绕晕了,于是找了很多资料:看了小甲鱼的数据结构系列教程的KMP内容总算了解的一知半解,在这个过程中也看到了其他的模式匹配算法如:BF算法 KMP算法 BM算法 sunday算法
sunday算法在后三个里面是比较容易理解的这里就总结一下这三天sunday算法
原理:
1.先比较模式串P和匹配串S是否相等 若相等则返回若不相等进行第二步
2.判断S的下一位字符是否在P里面 若在则将P中相同的字符(从后面算起第一个)移到与S下一位字符对齐
若不在则则将P的开头对齐S的下下位
3.一直循环下去直到找到的结果
比如:
匹配串:O U R S T R O N G X S E A R C H
模式串:S E A R C H
这里我们看到O-S不相同,我们就看匹配串中的O在模式串的位置,没有出现在模式串中。
匹配串:O U R S T R O N G X S E A R C H
模式串: _ _ _ _ _ _ _ _ S E A R C H
移动模式串,使模式串的首字符和O的下一个字符对齐。
匹配串:O U R S T R O N G X S E A R C H
模式串:_ _ _ _ _ _ _ _ S E A R C H
继续比较,N-S不相同,字符R出现在模式串,则后移模式串,将把它们对齐
匹配串:O U R S T R O N G X S E A R C H
模式串: _ _ _ _ _ _ _ _ _ _ _ S E A R C H
主要实现的函数
第一个判断pattern中的字符串是否和string中的字符串是否相等int comparePatternAndString(char *pattern,int plen,char *str,int currentLocationInString) { int i=plen-1;//i=2 int tag=1;//标识符,如果有一个不匹配,tag为0. while(i>=0 && tag==1) { if(pattern[i]!=str[currentLocationInString])//从后面开始对比是否相等 tag=0; i--; currentLocationInString--; } return tag;//tag=1表示成功,否则失败。 }第二个函数是判断string的后一位是否在pattern中 不在返回0 在返回它的位置
int IsinthePattern(char a,char *pattern,int plen)//这里的a传过来的是下一位字符 { int i=plen-1; int tag=0; while(i>=0 && tag==0) { if(pattern[i]==a) tag=1; i--; } if(tag==1) return i+1;//若在pattern中,返回最右边的匹配的位置。 else return 0;//没有匹配,就返回0 }具体代码(含详细注释)
//思路分析: //1.comparePatternAndString函数 #include<iostream> using namespace std; int comparePatternAndString(char *pattern,int plen,char *str,int currentLocationInString) { int i=plen-1;//i=2 //int j=currentLocationInString;//j=2 int tag=1;//标识符,如果有一个不匹配,tag为0. while(i>=0 && tag==1) { if(pattern[i]!=str[currentLocationInString])//从后面开始对比是否相等 tag=0; i--; currentLocationInString--; } return tag;//tag=1表示成功,否则失败。 } int IsinthePattern(char a,char *pattern,int plen) { int i=plen-1; int tag=0; while(i>=0 && tag==0) { if(pattern[i]==a) tag=1; i--; } if(tag==1) return i+1;//若在pattern中,返回最右边的匹配的位置。 else return 0;//没有匹配,就返回0 } int main() { char *string1="fgjsderiodfda1546egdjkjdkfdadghh";//匹配串 char *pattern="fda";//模式串 int find=0,in=0,tag=1; int currentPosition=0; int length,plen; plen=strlen(pattern);//plen是模式串的长度 plen=3 currentPosition=plen-1;//目前对齐后的最后一个下标。currentPosition=2 length=strlen(string1);//匹配串的长度 length=32 if(plen>length)//如果模式串的长度大于匹配串的长度那么输出错误提示:模式串的长度要小于匹配串的长度 { cout<<"the pattern is longer than string,we can not compare."<<endl; } //tag用来标识是否应该结束。匹配成功与否还是要看find。 while(tag==1) { //这个函数的功能是比较pattern和string1中对应得字符串是否相等,若相等返回1否则返回0 find=comparePatternAndString(pattern,plen,string1,currentPosition);// //若不匹配 现在就要判断后一个字符是否在pattern中 if(find==0) { //找到末尾了没有找到。 if(currentPosition+1==length)//currentPosition是对齐后的最后一个下标,加1==length的话表示已经找到末尾了 { tag = 0; } //还没有到末尾 else { //IsinthePattern这个函数判断后一个字符是否在pattern中,若在返回它的位置,若不在返回0 in=IsinthePattern(string1[currentPosition+1],pattern,plen);//string1[currentPosition+1]是后一个的字符 //没有在pattern里面,跳过。 if(in==0)//当后面一个字符不在pattern中的时候 { //后面的不足plen位,找不到了。 if(currentPosition+1+plen>length) { tag = 0; } else { currentPosition=currentPosition+1+plen;//重定位currentPosition } }//if(in==0) //这个字符在pattern里面 in=1 else { currentPosition=currentPosition+plen-in; } } }//if(find==0) else//这个else对应的是find==1,也就是找到了把tag=0跳出这个循环 tag=0; }//while if(find==0) cout<<"there is no pattern in the string."<<endl; if(find==1) cout<<"there is a pattern in the string.and the position is "<<currentPosition-plen+1<<endl; return 0; }这里面比较难理解的就是currentPosition
currentPosition是一个不断指向匹配串并且和模式串最后一个字符对齐的“指针”
心得:最简单的BF算法和高效率的sunday算法都弄懂了,接下来找个时间还需要总结一下BM算法和苦涩难懂的KMP算法
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 数据结构之Treap详解
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解