• KMP模版 && KMP求子串在主串出现的次数模版


    求取出现的次数 : 

    #include<bits/stdc++.h>
    const int maxn = 1e6 + 10;
    char mo[maxn], str[maxn];///mo为模式串、str为主串
    int next[maxn];
    inline void GetNext()
    {
        int i = 0, j = -1, len = strlen(mo);
        next[i] = j;
        while(i < len){
    //        if(j == -1 || mo[i] == mo[j]) next[++i] = ++j;
    //        else j = next[j];
            while( j != -1 && mo[i] != mo[j]) j = next[j];
            next[++i] = ++j;
        }
    }
    int KmpCount()///计算模式串在子串出现的次数
    {
        GetNext();
        int i = 0, j = 0, strL = strlen(str), moL = strlen(mo);
        int ans = 0;
        while(i < strL){
            while( j != -1 && mo[j] != str[i]) j = next[j];
            i++, j++;
            if(j == moL) ans++;
        }
        return ans;///返回模式串在主串中出现的次数(可重叠出现)
    }
    int main(void)
    {
        scanf("%s %s", str, mo);
        printf("%d
    ", KmpCount());
        return 0;
    }
    View Code

    求模式串第一次在主串出现的位置 or 匹配是否在主串出现过 :

    #include<bits/stdc++.h>
    const int maxn = 1e6 + 10;
    char mo[maxn], str[maxn];///mo为模式串、str为主串
    int next[maxn];
    inline void GetNext()
    {
        int i = 0, j = -1, len = strlen(mo);
        next[i] = j;
        while(i < len){
            while( j != -1 && mo[i] != mo[j]) j = next[j];
            next[++i] = ++j;
        }
    }
    int KmpIndex()
    {
        GetNext();
        int i =0, j = 0, strL = strlen(str), moL = strlen(mo);
        while(i < strL && j < moL){
            while( j != -1 && str[i] != mo[j]) j = next[j];
            i++, j++;
        }
        if(j == moL) return i - moL;///返回模式串在主串中首次出现的位置
        else return -1;
    }
    int main(void)
    {
        scanf("%s %s", str, mo);
        printf("%d
    ", KmpIndex());
        return 0;
    }
    View Code

    ///--------------------------------------------------------------------------------------------------------------------------

    KMP算法的解释尤其是next数组可以参考这个博客 : http://blog.csdn.net/yutianzuijin/article/details/11954939/ 

    这个是我对KMP的next数组的一点理解,都写在注释里面了

    #include<bits/stdc++.h>
    const int maxn = 1e6 + 10;
    char mo[maxn], str[maxn];///分别为模式串和子串
    int next[maxn];
    /// next[i] 可以"翻译"成 i 这里失配了,考虑 0~(i-1) 这个
    /// 串,看能否找到一个位置 k 和 k' 使得前缀 0~k 和后缀 
    /// k'~(i-1)一样,而next[i]存储的就是 k+1 这个位置,即
    /// 前缀的前一个
    inline void GetNext()
    {
        int i = 0, j = -1, len = strlen(mo);
        next[i] = j;
        while(i < len){
            while( j != -1 && mo[i] != mo[j]) j = next[j];
            next[++i] = ++j;
        }
    }
    ///-------------------------------------------------------------
    ///可以用下面的图来动态演示一下GetNext()的步骤,可能就能够理解
    //                  i              
    //- 0 1 2 3 4 5 6 7 8
    //  a b c a b c a d x
    //  - 0 0 0 1 2 3 4 0           
    //                  a b c a b c a d x 
    //                  - 0 0 0 1 2 3 4 0          
    //                  j
    ///下面有几句话可能能帮助理解
    ///①找next的值相当于就是拿模式串自己和自己匹配,在下面移动的就是后缀,在上面的就是前缀
    ///②当前匹配的字符以及其前面的字符的next值肯定是已经求出来的
    ///③当j==-1的时候就说明现在的i连模式串的第一个都不能匹配到
    ///④如果是判断当前的 i 和 j 则说明是在为 i+1 这个字符寻找 0~i (即i+1后的字符串)是否拥有相同前后缀
    ///--------------------------------------------------------------
    int KmpCount()
    {
        GetNext();
        int i = 0, j = 0, strL = strlen(str), moL = strlen(mo);
        int ans = 0;
        while(i < strL){
            while( j != -1 && mo[j] != str[i]) j = next[j];///匹配的时候当 j == -1 的时候就已经是第
            i++, j++;                                      ///一个现在的主串 i 连模式串的第一个都不
            if(j == moL) ans++;                            ///能匹配,所以下面让 i++,因为 j == -1,
        }                                                  ///所以 j++ 后自然是子串第一个
        return ans;
    }
    View Code
  • 相关阅读:
    关于勉励
    jQuery MiniUI
    DES 加密解密
    软件设计的原则
    关于jFinal
    医疗保险,公积金、养老、生育、工伤、失业保险
    GET和POST的区别(详解)
    单例模式
    ajax 同步和异步的区别
    tomcat部署web项目的3中方法
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/6883166.html
Copyright © 2020-2023  润新知