KMP子串查找算法

Posted 为了财务自由!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMP子串查找算法相关的知识,希望对你有一定的参考价值。







那么部分匹配表怎么获得?




实现关键

  1. PMT[1]=0;(下标为0的元素匹配值为0)
  2. 从2个字符开始递推(从下标为1的字符开始递推)
  3. 假设PMT[n]=PMT[n-1]+1(最长共有元素的长度)
  4. 当假设不成立,PMT[n]在PMT[n-1]的基础上减小


部分匹配表是前辈找到的规律,不需要理解,会用就行!
获得部分匹配表函数如下:

int* make_pmt(const char* p)

    int len = strlen(p);
    int* ret = static_cast<int*>(malloc(sizeof(int)*len));

    if(ret != NULL)
    
        int ll=0;
        ret[0]=0;
        for(int i=1;i<len;i++)
        
            while( (ll>0) && (p[ll]!=p[i]))
            
                ll = ret[ll-1];
            
            if( p[ll] == p[i] )
            
                ll++;
            
            ret[i]=ll;
        
    

    return ret;

测试:

int main()

    int* pmt = make_pmt("abcdabd");

    for(int i=0;i<strlen("abcdabd");i++)
    
        cout << i << ":" << pmt[i] << endl;
    


    return 0;


和上面一致

KMP算法实现:

int kmp(const char* s,const char* p)//O(m+n)

    int ret = -1;
    int sl=strlen(s);
    int pl=strlen(p);
    int* pmt=make_pmt(p);
    if((pmt != NULL) && (0<pl) && (pl<=sl))
    
        for(int i=0,j=0;i<sl;i++)
        
            while((j>0) && (s[i] != p[j]))
            
                j = pmt[j-1];
            

            if(s[i] == p[j])
            
                j++;
            

            if(j == pl)//查找到
            
                ret = i+1-pl;
                break;
            
        
    
    free(pmt);
    return ret;

这你妈是人能写出来的?

以上是关于KMP子串查找算法的主要内容,如果未能解决你的问题,请参考以下文章

串串的模式匹配算法(子串查找)BF算法KMP算法

KMP子串查找算法

子字符查找KMP算法 - 子串自匹配索引表

算法 - KMP算法

[C语言] 查找字符串出现次数-非KMP算法

字符串的模式匹配——Brute-Force算法和KMP算法