• KMP算法


    问题:很经典,也很难,理解了一个下午。。。终于把KMP算法思想弄明白了。改天继续看看。

    昨天写的,今天继续补充,KMP算法是由三个人发明的,KMP就是三个人名字的首字母。

    下面开始讲这个经典的算法:

    1、刚开始比较时,如果相等,下移;

    2、继续比较,遇到不相等的,假设位置为j,然后找j之前最大长度相等的前缀和后缀。这个怎么找不好理解,但理解了就很简单。

    用子串(现在作为主串)的第一个字符和j位置之前的第一个字符比较,如果相等,继续比较,第二个字符和j之前的第二个字符往后比较,。。。记录最大长度相等的前缀和后缀。

    3、如果没有,则主串和子串都增1。

    next数组的求法:

    首先,初始化。next[0]=-1;next[1]=0;

    其次,按照上面2的方法求next[j];其中j指的是子串中出现不匹配的情况,而next[j]本身指的是下次主串要与子串匹配的字符。

    最后,当j等于子串长度时,匹配成功。

    i-j就是匹配的起始位置,i是主串中最后匹配的位置。

    代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    void getNext(char *s,int *next)
    {
    	int k=-1,i=0;
    	next[0]=-1;
    	while(i<strlen(s)-1)
    	{
    	if(k==-1||s[i]==s[k])
    	{
    		k++;
    		i++;
    		next[i]=k;
    	}
    	else
    	{
    		k=next[k];
    	}
    	}
        
    }
    
    int KMPMatch(char *s,char *str)
    {
    	int next[100];
    	int i=0,j=0;
    	getNext(str,next);
    	while(i<strlen(s))
    	{
    	if(j==-1||s[i]==str[j])
    	{
           i++;
    	   j++;
    	}
    	else
    	{
    	  j=next[j];
    	}
    	 if(j==strlen(str))
    		 return i-strlen(str);
    	}
    	return -1;
    }
    
    int main()
    {
    	char *s="abcebabcdecada";
    	char *str="abcd";
    	int n;
    	n=KMPMatch(s,str);
    	if(n==-1)
    		cout<<"未找到匹配字符串"<<endl;
    	else
    	cout<<"匹配的起始位置为:"<<n<<endl;
    
    	return 0;
    }
    

    运行结果:

  • 相关阅读:
    StarUML 破解方法
    String、StringBuilder、StringBuffer对比
    ThreadLocal源码
    编程思想——访问权限控制
    设计模式——调停者模式
    Abp.vNext 权限备注
    Abp 中 模块 加载及类型自动注入 源码学习笔记
    使用 ZipArchive 生成Zip文件备注
    ORACLE 连接SQLSERVER 数据库备忘
    FastReport 自定义数据集
  • 原文地址:https://www.cnblogs.com/xshang/p/3045984.html
Copyright © 2020-2023  润新知