zoukankan      html  css  js  c++  java
  • [模板] [KMP] 字符串匹配

    拓展kmp

    
    int Next[MAXN], extand[MAXN];
    
    char s[MAXN];
    
    void getNext(char *T)
    {// Next[i]: 以第i位置开始的子串 与 T的公共前缀 
    	int i, length = strlen(T);
    	Next[0] = length;
    	for(i = 0; i < length - 1 && T[i] == T[i+1]; i++);
    	Next[1] = i;
    	int a = 1;
    	for(int k = 2; k < length; k++)
    	{
    		int p = a+Next[a]-1, L = Next[k-a];
    		if((k - 1) + L >= p )
    		{
    			int j = (p - k + 1) > 0 ? (p - k + 1) : 0; 
    			while(k + j < length && T[k + j] == T[j]) 
    				j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 
    			Next[k] = j, a = k;
    		} 
    		else 
    			Next[k] = L;
    	} 
    }
    
    void getextand(char *S,char *T)
    {
    	memset(Next,0,sizeof(Next));
    	getNext(T);
    	int Slen = strlen(S), Tlen = strlen(T), a = 0;
    	int MinLen = Slen > Tlen ? Tlen : Slen;
    	while(a < MinLen && S[a] == T[a]) a++;
    	extand[0] = a, a = 0;
    	for(int k = 1; k < Slen; k++)
    	{
    		int p = a + extand[a] - 1, L = Next[k-a];
    		if((k - 1) + L >= p )
    		{
    			int j = (p - k + 1) > 0 ? (p - k + 1) : 0;
    			while(k + j < Slen && j < Tlen && S[k + j] == T[j]) j++;
    			extand[k] = j; a = k;
    		} 
    		else extand[k] = L;         
    	}
    }

    KMP 

    #include <iostream>
    using namespace std;
    
    typedef long long ll;
    
    const int MAXN = 1e5 + 10;
    
    string a, text;
    
    ll pre[100010] = {-1};
    
    
    void prefix_table(string mode)
    {
        for(int i = 1, j = 0; i < mode.length(); i++)
        {
            if(mode[i] == mode[j])
            {
                pre[i + 1] = pre[i] + 1;
    
                j++;
            }
            else    //若匹配不上再次匹配时从零开始
            {
                j = 0;
    
                if(mode[i] == mode[j])    //从零的第一个单独判断一
                {    
                    pre[i + 1] = 1;
                    
                    j++;
                }
    
            }
        }
    }
    
    int judge(int beg, int end,int lenm) //向后跳转匹配
    {
        int i = beg - 1, j = 0, ans = 0;
        
        while(i < end)
        {
            if(j == lenm - 1 && text[i] == a[j])
            {
                ans++;
            }
            if(text[i] == a[j])
            {
                i++;
                j++;
            }
            else
            {
                j = pre[j];
                if(j==-1)
                {
                    i++;
                    j++;
                }
            }
        }
        return ans;
    }
    
    
    int main()
    {
        int lent, lenm, t;
    
        cin>>lent>>lenm>>t;
    
        cin>>text>>a;
    
        prefix_table(a);
        
        while(t--)
        {
            int beg, end;
    
            cin>>beg>>end;
            
            cout<<judge(beg, end, lenm)<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    CSS样式
    Python宏观
    javaScript----------(函数)
    vue-----5计算属性
    python之函数作用域、嵌套以及闭包
    python之函数的定义、传参以及动态参数
    python之文件操作
    基础数据类型的补充以及深浅copy
    小数据池、代码块以及编码转换
    python基础二
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270523.html
Copyright © 2011-2022 走看看