• KMP算法总结&代码


    KMP是经典的字符串匹配算法,时间复杂度为o(m+n)

    KMP原理

    (待补充)

    前一阵子自己试着写了一下,代码如下:

    /*
    *KMP算法实现
    *包含两部分:1.模式串前缀函数的计算(预处理)
    *			 2.文本与模式串的匹配
    *
    *模式串前缀函数的计算(预处理):
    *假设模式串的长度为len,通过计算模式串从1到len为止的所有子串的
    *最大前缀长度,来填充前缀数组。这个前缀满足这种特性:是这个子串的
    *真后缀,而且是这个子串的真前缀(即不为子串本身),能满足以上两者
    *的最大的那个串,取其长度。例如:abcabc,其中abc既是这个子串的后缀,
    *也是这个子串的前缀,并且是最长的,所以其前缀函数值为3.
    *
    *计算所有子串的前缀函数值:
    *从第一个字符开始计算,因为第一个字符没有真前缀,所以取0
    *接下来,对每个子串,进行判断,如果失配,则回溯到之前更短的前缀值
    *看是否有一个与之可以匹配的。如果匹配,则直接在原有值+1,并移动指针
    *例如:abkabcabkabk,当运行到k时,这时前缀指针在c,c!=k,因此失配,通过
    *循环返回到abkab的最长前缀值,即2,此时前缀指针指向k,k==k,因此匹配,
    *跳出循环,在目前的基础上+1,即为3.前缀指针继续向前移动到a
    */
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    void compute_prefix(char pattern[100],int prefix[100]){
    	int len=strlen(pattern),i,prelen;
    	prefix[0]=0;
    	prelen=0;
    	for(i=1;i<len;i++){
    		while(prelen>0&&pattern[prelen]!=pattern[i])
    			prelen=prefix[prelen-1];
    		if(pattern[prelen]==pattern[i])
    			prelen++;
    		prefix[i]=prelen;
    	}
    };
    int main(){
    	char text[1000],pattern[100];
    	int prefix[100],i,q=0;
    	while(scanf("%s%s",text,pattern)!=EOF){
    		compute_prefix(pattern,prefix);
    		for(i=0;i<strlen(text);i++){
    			while(q>0&&pattern[q]!=text[i])
    				q=prefix[q-1];
    			if(pattern[q]==text[i])
    				q=q+1;
    			if(q==strlen(pattern)){
    				printf("pattern occurs:%d",i+1-strlen(pattern));
    				q=prefix[q-1];
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    MyBatis学习(三)
    MyBatis学习(二)
    Linux(Ubuntu)下MySQL的安装与配置
    IO 流读取文件时候出现乱码 文件编码格式问题 怎么转换解决方法
    spring boot下MultipartHttpServletRequest如何提高上传文件大小的默认值
    Mybatis 批量插入时得到插入的id(mysql)
    对PDF的操作
    利用nginx进行集群部署
    Spring boot学习笔记之@SpringBootApplication注解
    git的使用命令
  • 原文地址:https://www.cnblogs.com/hrlnw/p/3076468.html
Copyright © 2020-2023  润新知