zoukankan      html  css  js  c++  java
  • 复习—KMP算法

    对于KMP算法的学习,在寒假时我还是搞不太明白,但几个月之后,对于它的理解又更近了一步。

    首先是对于子串的自我匹配,求一个fail数组,fail[i]对于字符串SS的前ii个字符构成的子串,既是它的后缀又是它的前缀的字符串中(包括他),最长的长度记作fail[i]

    举个例子,abcdabc中fail[7]的值就是3。当我们失配的时候,就直接跳到fail[i]所指的值上,这样效率就提升很大。

    同理,子串和模式串匹配也是这个套路。对于KMP算法的讲解,建议去bilibili上有一个印度人的视频讲的还比较清楚。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e7+7;
    int fail[maxn],show[maxn];
    char s1[maxn],s2[maxn];
    int ans;
    int len1,len2;
    int j;
    void getfail(){
        fail[1]=0;
        for(int i=2;i<=len2;i++){
            while(j!=0&&s2[i]!=s2[j+1]) j=fail[j];
            if(s2[i]==s2[j+1]) j++;
            fail[i]=j;
        }
    } 
    void kmp(){
        j=0;
        for(int i=1;i<=len1;i++){
            while(j!=0&&s1[i]!=s2[j+1]) j=fail[j];
            if(s1[i]==s2[j+1]) j++;//母串不动,子串自己动
            if(j==len2){
                ans++;
                show[ans]=i-len2+1;//求子串出现的位置
            } 
        }
    }
    int main(){
        scanf("%s%s",s1+1,s2+1);
        len1=strlen(s1+1);
        len2=strlen(s2+1);    
        getfail();
        kmp();
        for(int i=1;i<=ans;i++){
            printf("%d
    ",show[i]);
        }
        for(int i=1;i<=len2;i++){
            printf("%d ",fail[i]);
        }
        return 0;
    }
  • 相关阅读:
    Oracle如何定义两个数组变量
    Oracle 数组定义
    Oracle的Number对应C#数据类型
    Oracle删除临时表
    我的第一个Flutter 项目(电商)
    Dart Mac 安装环境(无敌)
    React Native 问题(运行)
    TS的一些用法和普通的对比(Vue)
    vue2.0和vue3.0的响应式原理
    简易orm 主要是为了旧平台查询方便
  • 原文地址:https://www.cnblogs.com/LJB666/p/11026729.html
Copyright © 2011-2022 走看看