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;
    }
    
  • 相关阅读:
    Codeforces 1255B Fridge Lockers
    Codeforces 1255A Changing Volume
    Codeforces 1255A Changing Volume
    leetcode 112. 路径总和
    leetcode 129. 求根到叶子节点数字之和
    leetcode 404. 左叶子之和
    leetcode 104. 二叉树的最大深度
    leetcode 235. 二叉搜索树的最近公共祖先
    450. Delete Node in a BST
    树的c++实现--建立一棵树
  • 原文地址:https://www.cnblogs.com/xxrlz/p/10473994.html
Copyright © 2011-2022 走看看