zoukankan      html  css  js  c++  java
  • Kmp 模板

    kmp算法

    通过预处理出next表

    将字符串匹配复杂度降为O(n+m)

    在串与模式匹配的过程中 串下标永远向前走,而模式下标则通过next进行回溯比较,next[0] =-1 是特殊的位置,当回溯到-1时说明当前串与模式无法匹配,需要移动串下标

    而在构造next数组的过程中 相当于进行了自身与自身的匹配 所以next数组与源串并没有关系

    next数组总等于当前位置所对应的最长前缀最长后缀 相同的长度 只有这样才会在转移的过程中不会遗失可能相等的地方

    #include<bits/stdc++.h> 
    using namespace std;
    
    const int maxn = 1000010;
    int Next[maxn];
    void getNext(string str)
    {
    	int m = str.length();
        Next[0] = -1;
        int j = -1;
        int i = 0;
        while(i<m)
        {
        	if(j==-1 || str[i]==str[j])//如果j为-1 或能够匹配上,则将i j后移并记录Next[i] 为当前的j
            {	
            	i++,j++;
            	Next[i] = j; 
            }   
            else j = Next[j];	//如果匹配不上 则将j回溯
        }	
    }
    
    void kmp(string t,string p)
    {
    	int i=j=0;
        while(i<t.length())
        {
        	if(j==-1||t[i]==p[j])//如果回溯到了开始 或能够匹配上 则将i,j后移
            {
            	i++,j++;	
            }
            else//	匹配不上 回溯j
            	j=Next[j];
            if(j==p.length())	//已经匹配成功
            {
            	cout << i-j+1<<endl;
                j = 0;			//归零j
            }
        }
    }
    
    int main()
    {
    	string s1,s2;
        cin>>s1>>s2; 
        getnext(s2);
        kmp(s1,s2);
        for(int i=1;i<=s2.length();++i)
        	cout <<Next[i] << ' ';
        return 0;
    }
    
  • 相关阅读:
    bzoj2124 等差子序列(树状数组+hash)
    CF817F MEX Queries(线段树上二分)
    [USACO12MAR]摩天大楼里的奶牛(状态压缩DP)
    CF786B Legacy(线段树优化建图)
    绿豆蛙的归宿
    单选错位
    聪聪和可可
    Tyvj1952 Easy
    OSU!
    弱题
  • 原文地址:https://www.cnblogs.com/xxrlz/p/10473994.html
Copyright © 2011-2022 走看看