• KMP 字符串匹配 学习笔记


    写在前面:
    建议大家先去看洛谷P3375这道题,结合题目食用风味更佳

    算法的原型:暴力朴素算法(不上代码了因为我懒):将原串与用于匹配的串一位一位的匹配,时间复杂度(O_(nm))

    改进方法:使用一个next数组来记录用于匹配的串的这个点之前的串前缀与后缀的最大匹配位数

    举个例子:
    (S_1="ABABABABABC")
    (S_2="ABABA")

    那么,我们定义一个指针k指向(S_2)当前第k个字符,next[k]就是k之前的串中前缀后缀的最大匹配位数,根据这一点,我们可以将next[0]初始化为-1(或者是将next[1]初始化为0)

    这样,我们就可以通过(O_(m))的预处理处理出每一个next,代码如下

    void pre(char s[]){
    	int k=-1,l=strlen(s);
    	nxt[0]=-1;
    	for(int i=1;i<l;++i){//这里从1开始是为了匹配后缀
    		while(k>-1&&s[k+1]!=s[i])k=nxt[k];
    		if(s[k+1]==s[i])k++;
    		nxt[i]=k;
    	}
    	return;
    }
    

    算法核心:利用处理出来的next省去冗余的扫描,让时间复杂度成为线性的(O_(n+m))

    具体实现:不好说,我水平还不够,以后补

    先上代码,可能比较难以理解,请见谅:

    void kmp(char s[],char p[]){
    	int k=-1;
            int l1=strlen(s),l2=strlen(p);
    	for(int i=0;i<l1;++i){//与预处理相似,预处理其实就是自己与自己匹配
    		while(k>-1&&p[k+1]!=s[i])k=nxt[k];
    		if(p[k+1]==s[i])++k;
    		if(k==l2-1){
    			printf("%d
    ",i-l2+2);
    			k=nxt[k];
    		}
    	}
    	return;
    }
    

    现在还不是特别明白,先写在这里,等哪一天恍然大悟在更新(咕咕咕)

  • 相关阅读:
    科技爱好者周刊(第 175 期):知识广度 vs 知识深度
    科技爱好者周刊(第 173 期):网络收音机的设计
    Telegra.ph | 简洁的文章发布平台
    前端规范
    Vue入门笔记三(Vuex)
    Vue入门笔记二
    Vue入门笔记一
    多点商城小程序案例笔记一
    sublime text 笔记
    windows下安装SASS
  • 原文地址:https://www.cnblogs.com/dclicker/p/9886135.html
Copyright © 2020-2023  润新知