sunday算法

前言:从看大话数据结构的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算法

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值