码迷,mamicode.com
首页 > 其他好文 > 详细

KMP【模板】

时间:2015-05-03 23:46:36      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

当字符串匹配失败时,模式串的指针并没有指向0从头比较,而是指向了一个特定的位置,因为这个Next[j]指向的位置pos前长度为Next[pos]的子串,同模式串第j位前的长度为Next[j]的子串是相同的。
即S[0]~S[Next[j]]一定与S[len-1-Next[j]]~S[j-1]匹配。
1.既能做前缀又能做后缀的子串长度

 ans[0] = len;  
        int id = 1,i = len;  
        while(Next[i] > 0)  
        {  
            ans[id++] = Next[i];  
            i = Next[i];  
        }  

2.求最短子串长度
给定的字符串s,最短的重复子串a是s[Next[len]] s[Next[len+1]] … s[len-1]。
当len % Next[len] = 0时,说明字符串s有不是它本身重复子串a,最大的n为len/Next[len]。当len % Next[len] != 0时,除了s,没有重复子串a满足要求,这时n = 1。

if(len % (len-Next[len]) == 0)  
            cout << len/(len-Next[len]) << endl;  
        else  
            cout << 1 << endl;  

3.求模式串pat在主串str中匹配次数
可重叠匹配:当一次匹配成功后,j继续回退到Next[j]向后进行匹配,直到主串str的末尾。
不可重叠匹配:当一次匹配成功后,j继续回退到0向后进行匹配,直到主串str的末尾。
4.求N行M列的字符矩阵,最小的字符子矩阵的面积
每一行s[i]来说,M-Next[M]是最小的,对于每一列s[j]来说,N-Next[N]是最小的。
分别求每一行的最小公倍数lcmn和每一列的最小公倍数lcmm。最后结果就是lcmn*lcmm。
5.求字符串s的循环前缀的长度和循环的次数
对于当前前缀S[1]~S[i],如果i % (i-Next[i]) == 0,则i - Next[i]就是最小重复子串,即循环节长度为i - Next[i]。循环次数为i / (i - Next[i])。

char str[1000010],pat[1000010];//pat为模式串,str为主串
int Next[1000010]; //Next[x]下标x表示匹配失败处字符下标
//模式串pat的前缀与x位置的后缀的最大匹配字符个数-1
void GetNext(char *pat)
{
    int LenPat = strlen(pat);
    int i = 0,j = -1;
    Next[0] = -1;
    while(i < LenPat)
    {
        if(j == -1 || pat[i] == pat[j])
        {
            i++,j++;
            Next[i] = j;
        }
        else
            j = Next[j];
    }
}

int KMP()//返回模式串pat在str中第一次出现的位置
{
    int LenStr = strlen(str);
    int LenPat = strlen(pat);
    GetNext(pat);
    int i = 0,j = 0;
    int ans = 0;//计算模式串在主串匹配次数
    while(i < LenStr)
    {
        if(j == -1 || str[i] == pat[j])
            i++,j++;
        else
            j = Next[j];
        if(j == LenPat)
        {
            //ans++; ans存放匹配次数,去掉return,最后返回ans
            return i - LenPat + 1;
        }
    }
    return -1;//没找到匹配位置
    //return ans;//返回匹配次数。
}

KMP【模板】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45462835

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!