算法导论-字符串匹配

编辑文本时,我们经常需要在文本中找到某串模式字符在整个文本中出现的位置,这个模式字符串即为用户查找输入的关键字,解决这个问题的算法为字符串匹配算法。
这里写图片描述
当我们遇到这个问题,如何查找在文本中出现的模式呢?
一:朴素字符串匹配
我们假设存在两个游标i,j分别指向文本串与模式串的位置,那么有
1:当匹配到T[i]==P[j],则i++,j++;
2:当在匹配到某一位置时出现T[i]!=P[j]时,即匹配失败,此时i回溯到本次开始匹配的位置,j=0
咱们从代码与匹配图解理解朴素算法思路:

int native_string_matcher(char* T,char* P)
{
//获取原始串和模式串字符长度
    int n=strlen(T);
    int m=strlen(P);
    int s=0,i=0;
    //原串开始从0至n-m偏移,以匹配模式串
    for(s=0;s<=n-m;s++)
    {
//模式串从0-m开始分别匹配模式串中字符是否与原串相等
        for(i=0;i<m;i++)
        {
            if(P[i]!=T[s+i]) //如果在匹配过程中有字符不相等,则跳出该循环,偏移S向下移位,继续重新匹配
            {
                    break;
            }
            if(i==m-1)//当i=m-1,且P最后字符与T最后字符相等,则表示字符串匹配成功,此时返回原串中与模式串相匹配的起始位置。
                    printf("has match");
                    return s;
        }
    }
}

OK,现在我们举个栗子,
假设有一个文本字符串和模式字符串如下图
这里写图片描述
(a) 字符串开始匹配,此时T[0]=P[0],i++为1,此时s+i=1,T[1]!=P[1],匹配失败,s自加1,变为1,开始图(b)的匹配过程;
(b) 此时T[s=1]=c!=P[0],匹配失败,s自加1,变为图c的匹配过程
(c) 此刻T[s=2]=P[0],i自加1,T[s+i=3]=P[i=1],字符相等,继续下一匹配,i自加1为2,T[s+i=4]=P[i=2],且此刻i=length(P),匹配结束。此刻,s继续自加,进行余下字符串的匹配。
朴素字符串匹配过程较简单,但是最坏情况下时间复杂度为O((n-m+1)*m),字符串的匹配时间开销较大,并不能很好的解决字符串的匹配。
补充:
在朴素字符串匹配中存在一种特殊情况,即模式串P中的所有字符都不相同,其匹配时间可以达到O(n),具体的实现代码如下:

int native_string_matcher(char* T,char* P)
{
//获取原始串和模式串字符长度

    int n=strlen(T);
int m=strlen(P);
    int j=0,i;
    for(i=0,j=0;i<n;i++)
    {
            if(T[i]==P[j]&&j<m) ++j;

            else{
                if(j!=0)
                {
                    j=0;
                    --i;
                }
            }
            printf("%d\n",i);
            if(j==m)
                return i-m+1;
    }
    return -1;//若为-1,代表原始串中不包含模式串
}

这个实现过程很好理解,下面图示匹配过程:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值