zoukankan      html  css  js  c++  java
  • KMP 模板(修订,更易懂)

    KMP 模板(修订,更易懂)

    之前一篇博客简单介绍了KMP的原理,但当时写的模板两个字符串数组都是从下标为0开始的,逻辑有些混乱.

    这次修改了x,y下标从1开始,感觉更加自然.

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e6+5;
    const int M = 1e4+5;
    int xlen,ylen;
    int pre[M];
    char x[M]; 
    char y[N]; 
    
    // x 是模式串,y 是文本串,均从1开始
    void read_string(){
        scanf("%d%d",&xlen,&ylen);
        scanf("%s",x+1);
        scanf("%s",y+1);
    }
    
    // pre[i]: x串的长度为i的子串的公共前后缀长度
    void get_pre(){
        pre[0] = -1;
        pre[1] = 0;
        for(int i = 2; i <= xlen; ++i){
            if(x[i] == x[pre[i-1]+1]){
                pre[i] = pre[i-1] + 1;   
            }else{
                int ptr = pre[i-1] + 1;
                while(ptr >= 1 && x[ptr] != x[i]){
                    ptr = pre[ptr-1] + 1;
                }
    
                pre[i] = ptr;
            }
        }
    }
    
    int kmp_match(int ans[]){
        int cnt = 0;
        int xptr = 1,yptr = 1;
        while(xptr <= xlen && yptr <= ylen){
            if(xptr == 0 || x[xptr] == y[yptr]){
                ++xptr;
                ++yptr;
            }else{
                xptr = pre[xptr-1] + 1;
            }
    
            if(xptr == xlen + 1){
                // 注意此时x和y都已经向后移位了
                ans[++cnt] = yptr - xptr + 1;
                xptr = pre[xptr-1] + 1;
            }
        }
    
        return cnt;
    }
    
    
    int main(){
        read_string();
        get_pre();
        for(int i = 0; i <= xlen; i++){
            printf("pre[%d] = %d
    ",i,pre[i]);
        }
        int ans[10];
        int cnt = kmp_match(ans);
        for(int i = 1; i <= cnt; i++){
            printf("%d
    ",ans[i]);
        }
    
        system("pause");
        return 0;
    }
    
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    TCP和UDP的最完整的区别
    cluster模块实现多进程-让我的代理服务速度飞起来了
    redis多实例运行
    Nodejs实现代理服务器配置
    java统计程序运行的时间
    spring boot配置写法
    Redis: OOM command not allowed when used memory > ‘maxmemory
    最新版postgresql+pgboucer安装
    spring boot 数据库连接池配置
    Spring BOOT PERFORMANCE
  • 原文地址:https://www.cnblogs.com/popodynasty/p/13983688.html
Copyright © 2011-2022 走看看