字符串匹配之sunday算法

来源:互联网 发布:nba stat数据 编辑:程序博客网 时间:2024/06/05 13:08

虽然研究过KMP算法好几次了,可是一到用就忘记next怎么求法了,听说sunday算法比KMP效率高,而且简单易懂,老少皆宜,我就来尝尝鲜。看完以后,决定从今以后不再用KMP了,sunday真心是NiuBility的一个算法。

sunday的算法思路是这样的,从左端开始匹配,如果遇到不匹配的字符,那么每次都去看子串与母串最右端对齐的母串中的下一个字符(我称它为sunday字符),并从子串的右端开始去找sunday字符,找到了就将它们对齐,没有的话就整个子串移过去,从sunday字符的下一个字符开始匹配。比如下述例子:

aibdajobewhjo

ajo

到‘j’发现不匹配,这时母串与子串右端对齐的是‘b’,‘o’,下一个字符是‘d’,在子串中从右端开始找没发现有‘d’,于是直接移动4个位置从‘d’的下一个字符‘a’开始匹配。即如下:

aibdajobewhjo

       ajo

这时发现完全匹配,返回‘a’所在位置就结束了。总共就移动了一次。

下面贴上我写的很烂的一个算法,仅供参考:

#include<stdio.h>#include<string.h>int sunday(const char* str,const char* patt){int len_s,len_p;if(!str||!patt)return -1;len_s=strlen(str);len_p=strlen(patt);int move[256];//不匹配时,如果str的sunday字符(即patt末端的下一个位置的字符)的ASCII码为i,则move[i]存放要移动的距离for(int i=0;i<256;i++)//对于ASCII码为i的字符,移动位置为move[i],初始假设为len_p+1,即假设在patt没有出现move[i]=len_p+1;for(int i=0;i<len_p;i++)//反过来我们也可以这么想,将patt[i]看成sunday字符,那么要移动的距离就是len_p-i;从前往后扫一遍,如果在patt出现了重复的字符,保证会优先选择后面出现的字符move[*(patt+i)]=len_p-i;int si=0,pi=0,pos=0;while(pos<len_s-len_p+1){si=pos;for(pi=0;pi<len_p;pi++,si++){if(*(str+si)!=*(patt+pi)){pos+=move[*(str+pos+len_p)];break;}}if(pi>=len_p)return pos;}return -1;}int main(){char* str="ajf;eijfow";char* patt="ijf";printf("%d\n",sunday(str,patt));return 0;}


 

原创粉丝点击