串匹配问题的BF算法和KMP算法

习题:假设在文本“ababcabccabcacbab”中查找模式“abcac”,写出分别采用BF算法和KMP算法的串匹配过程。
1.BF算法:
简单的模式匹配
输入:主串S,模式T
输出:T在S中的位置
1.初始化主串比较的开始位置index=0;
2.在串S和串T中设置比较的起始下标i=0,j=0;
3.重复下述操作,直到S或T的所有字符均比较完毕:
3.1 如果S[i]=T[j],则继续比较S和T的下一对字符;
3.2 否则,下一趟匹配的开始位置index++,回溯下标i=index,j=0;
4.如果T中所有字符均比较完,则返回匹配的开始长度index;否则返回0;

#include <iostream>
using namespace std;
int BF(char S[],char T[])
{
    int index=0;
    int i(0),j(0);
    while((S[i]!='\0'&&T[j]!='\0'))
    {
        if(S[i]==T[j])  {i++;j++;}
        else
        {   index++;
            i=index;j=0; }
    }
    if(T[j]=='\0') return index+1;
    else return 0;
}
int main()
{
    char S[]={"ababcabccabcacbab"},T[]={"abcac"};
    cout<<BF(S,T)<<endl;
    return 0;
}

2.KMP算法
主要是针对一次匹配失败后,主串和模式的下标回溯的优化。

输入:主串S,模式T
输出:T在S中的位置
1.在串S和串T中分别设置比较的起始下标i=0,j=0;
2.重复下述操作,直到S或T的所有字符均比较完毕:
2.1 如果S[i]=T[j],则继续比较S和T的下一对字符串
2.2 否则将下标回溯到next[j],即j=next[j];
2.3 如果j=-1,则将下标i和j分别加1,准备下一次比较;
3.如果T中所有字符均比较完毕,则返回本趟匹配的开始位置,否则返回0;

#include <iostream>
#include <string>
using namespace std;
void GetNext(char T[],int next[])
{
    int i,j,len;
    next[0]=-1;
    for(j=1;T[j]!='\0';j++)
    {
        for(len=j-1;len>=1;len--)
        {
            for(i=0;i<len;i++)
               if(T[i]!=T[j-len+i]) break;
            if(i==len)
            {
                next[j]=len;break;
            }      
        }
        if(len<1) next[j]=0;
    }
}
int KMP(char S[],char T[])
{
    int i=0,j=0;
    int next[80];
    GetNext(T,next);
    while(S[i]!='\0'&&T[j]!='\0')
    {
        if(S[i]==T[j]) { i++;j++; }
        else
        {   j=next[j];
            if(j==-1) { i++;j++; }}
    }
    if(T[j]=='\0') return(i-strlen(T)+1);
    else 
    return 0;
}
int main()
{
    char S[]={"ababcabccabcacbab"},T[]={"abcac"};
    cout<<KMP(S,T)<<endl;
    return 0;
}

能够理解,也能够花时间磨出代码,等待继续熟悉。
还有next值的优化算法

  • 12
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值