• 【笔记】好背的KMP


    首先,KMP的原理请自行百度,不再赘述。

    来个好背的代码好了,给我背了半年的这个算法收个尾(

    首先,把KMP想象成一个图(或者叫自动机?),可以实现每次给一个字符和一个当前状态,跳到下一个状态。

    好,这就是这种写法的精髓了(

    上一下跳状态的代码:

    //state:当前状态
    //c:跳的依据
    //ch:模式串
    int go(int state,char c){
          while(1){
                if(ch[state]==c)return state+1;
                if(!state)return 0;
                state=fail[state];
          }
    }//其实递归更好背但是容易爆栈=w=
    //可以记忆化搜索优化,有的题有用
    

    然后接着几部分直接背也没啥的了(

    void build() {
          for(int i=1;ch[i+1];++i)fail[i+1]=go(fail[i],ch[i]);
          //ch[i+1]解释:i+1位还有字符(也就是没超边界)
          //要是i+1超边界了,fail[i+1]也就不会被用到了
    }
    void run(){
          for(int i=0,u=0;tom[i];++i){
                u=go(u,tom[i]);
                //此时u记录的是模式串匹配到了哪一位,接下来比如可以这样:
                if(!ch[u]){
                      //匹配上了,做些处理
                }
          }
    }
    

    最后上个板子代码:输入两个字符串a,b,求b在a中出现的次数和位置。

    一行a一行b。

    #include<bits/stdc++.h>
    using namespace std;
    char tom[10000009];
    char ch[10000009];
    int fail[10000009];
    int go(int state,char c){
      	while(1){
          	if(ch[state]==c)return state+1;
          	if(!state)return 0;
          	state=fail[state];
        }
    }
    void build() {
          for(int i=1;ch[i+1];++i)fail[i+1]=go(fail[i],ch[i]);
    }
    void run(){
          for(int i=0,u=0;tom[i];++i){
                u=go(u,tom[i]);
                if(!ch[u+1]){//最后一位失配,详见主函数处理
                      printf("%d
    ",i-u+2),u=fail[u];
                }
          }
    }
    int main(){
          freopen("pattern.in","r",stdin);
          freopen("pattern.out","w",stdout);
          cin>>tom;tom[strlen(tom)]='#';
          cin>>ch;ch[strlen(ch)]='%';
          build();
          run();
          return 0;
    }
    

    应该是对的吧(

    Over.

  • 相关阅读:
    指针简单笔记
    Subway Lines (树链剖分+线段树)
    C#运动控制指示灯闪烁和系统复位(两个子窗体交互:一个子窗体按钮控制另外一个子窗体的方法)
    C# “|” 和 “||” “&”和“&&”区别
    2022/4/112022/4/16
    《Effective Modern C++》概览
    实验一 密码引擎4国䀄算法交叉测试
    实验一
    关于DDMS不显示进程的解决方法
    JNI接口native函数调用过程
  • 原文地址:https://www.cnblogs.com/unyieldingtrilobite/p/13681948.html
Copyright © 2020-2023  润新知