您的位置:首页 > 理论基础 > 数据结构算法

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算法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 算法