• KMP,模式匹配算法


     

            我们经常会遇到一种情况是匹配两个字符串,看strPar中是否含有str子串,如果有则返回子串在父串strPar中的位置,如果不存在则返回false.

            很明显,我们可以通过暴力求解的方式解决该问题。即从strPar第一个字符和子串进行比较,若成功则返回第一个0,若不成功,再第二个字符开始比较,这样的时间复杂度为O(M*N).可以看出,这个复杂度是相当高的,那么我们有没有一种复杂度会降低呢?显然,有一种叫做KMP算法可以大大降低复杂度O(M+N)。该算法通过记忆的方式,避免了很多无用功。

           比如字符...p1,p2,p3.....p‘,p'',p'''...

           假设p1,p2和p',p''是一样的,当我们进行比较的时候若在p'''比较失败,只需推到p3与父串进行比较即可,因为他前面的肯定是相同的。同时父串并不需要倒退。

           那么到底怎么退,退多少呢?

            这就需要有一个记忆数组,比如abaabcac

     1 void getNext(const char* str,int next[]){
     2     int i=0,j=-1;
     3     next[i]=j;
     4     assert(str);
     5     while(i<(int)strlen(str)){
     6         if(j==-1||str[i]==str[j]){
     7             i++,j++;
     8             next[i]=j;
     9         }
    10         else
    11             j=next[j];
    12     }
    13 }

    得到了next数组之后,通过strPar和str比较。若相同则i++,j++;否则str往后退,即j=next[j];

    int Index(const char* strPar,const char* str,int next[]){
        int i=-1,j=-1;
        assert(strPar&&str);
        int m=strlen(strPar),n=strlen(str);
        while(i<m&&j<n){
            if(j==-1||strPar[i]==str[j])
                i++,j++;
            else
                j=next[j];
        }
        if(j==strlen(str))
            return i-j;
        else
            return -1;
    }

         版权所有,欢迎转载,但是转载请注明出处:潇一

  • 相关阅读:
    LVDS 数据通道详解 单8 单6
    MFC中CTime获取日期时间的方法
    Sqlite 修改字段的名称。
    SQLite 字段数据类型
    把View转化成Image
    iOS 键盘类型UIKeyboardType
    验证银行卡号格式是否正确
    获取手机wifi下的网络地址
    图形处理专题(文章收集)
    收藏的博客
  • 原文地址:https://www.cnblogs.com/xiaoyi115/p/3620565.html
Copyright © 2020-2023  润新知