KMP算法笔记

小记

今天做了美团笔试题,五个过了四个。美团的题目比较简单,反正比阿里巴巴的简单太多了,但是前面很简单的题浪费我不少时间。编程习惯确实不太好,拿到题目,看懂了,脑子里一到一个简单又暴力的方法就开始写,自信满满一提交就TLE,看到TLE才会去想到高级的算法。今天比较搞笑得还是,其中一个题提交明明显示的是超时,我误以为是答案错误,然后就在找bug,一直找不到才发现是超时了。脑袋瞬间一清醒,卧槽,这不就是个二分吗?于是重写,总算过了。
前面四道简单题浪费了不少时间,做到最后一个题目的时候大概只有半个小时了,没写完。是关于字符串匹配的,没时间了,写了个暴力匹配,一提交,编译错误。。。然后考试结束。。真是震惊了。下来一看原来是istringstream所在的库导错了,应该#include < sstream> 我include了一个 < strstream>,其实考试写题的时候就在想,这istringstream是在哪个库来着?

kmp算法

正好做到字符串匹配了嘛,之前在ACM俱乐部当小透明(起步太晚,跟不上啊,呜呜呜)的那小段时间内是学到kmp算法的,可惜没掌握到,到现在我就记得个next数组,哈哈哈。现在呢,就写篇博客,记下kmp算法吧,方便复习巩固。

《数据结构》严蔚敏中的代码

int Index_KMP(SString S, SString T, int pos)
{
    //利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法。
    //其中,T非空,1<=pos<=StrLength(S)
    int i = pos;
    int j = 1;
    while(i <= S[0] && j <= T[0])
    {
        if(j==0 || j<=T[0)
        {
            ++i;
            ++j;
        }
        else j = next[j];
        if(j>T[0])                   //匹配成功
            return i-T[0];
        else return 0;
    }
}
void get_next(SString T, int next[])
{
    //求模式串T的next函数值并存入数组next
    i = 1;
    next[1] = 0; 
    j = 0;
    while(i < T[0])
    {
        if(j==0 || T[i] == T[j]){++i; ++j; next[i] = j;}
        else j = next[j];
    }
}

浙大陈姥姥

void getNext(char* pattern)
{
     int i, j;
     int m = strlen(str);
     next[0] = -1;
     for(j=1;j<m;j++)
     {
         i = next[j-1];
          while((i>=0)&&(pattern[i+1]!=pattern[j]))
              i = next[i]; 
          if(next[next[j-1]+1]==next[j])
          {
              next[j] = next[j-1]+1;
          }
          else next[j] = -1;
     }
}
int kmp(char* str, char *pattern)
{
    int n = strlen(str);
    int m = strlen(pattern);
    if(n<m)
        return -1;
    int s, p;
    next = (int*)malloc(sizeof(int)*m);
    getNext(pattern,next);
    while(s<n&&p<m)
    {
         if(str[s]==pattern[p])
         {
             s++;
             p++;
         }
          else{
              if(p>0)
                   p = next[p-1]+1;
              else s++;
         }
         return p==m ? (s-m) : -1;
    }
}

未完待续,理解算法之后再码。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值