• KMP


    推荐博客 :http://www.cnblogs.com/yjiyjige/p/3263858.html

    什么是KMP 算法呢 ?

      KMP是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同时发现的。

    问题 :

      有两个字符串 , 一个叫模式串 , 一个叫主串 , 用模式串向主串匹配 , 传统的方法 , 暴力匹配,当模式串与主串不匹配时 ,模式串与主串都回溯, 用模式串向主串的下一个字母匹配 。

    这种暴力匹配效率很低 , 于是就产生了KMP这种思想 :  利用已经部分匹配这个信息,保持主串指针不回溯,通过修改模式串指针,让模式串尽量的移动到有效的位置。

    还有这个 :

    我感觉 , kmp 就是把人脑一眼可以看到的字符串匹配写成了机器语言 , 好了 , 下面介绍下如何确定 当模式串与主串不匹配时,如何求出模式串应该右移的位数 , 就会引入一个叫 next 的数组 。

    next 数组所存的东西就是当两个串不匹配时 , 模式串指针应该跳跃的位置 ,看一个图

    如何求next 数组呢 ?

      代码示例 :

      

    void getnext(){
        int i = 0, j = -1; // i表示后缀指针,j表示前缀指针
        next[0] = -1;
        while (i != lenp){ // lenp 表示模式串长度
            if(j == -1 || s[i] == s[j]) { // s 所存的是模式串
                i++;
                j++;
                next[i] = j;
            }
            else 
                j = next[j];
        } 
    }

    // 前缀时确定的,后缀是相对的

    关于next 有两种写法 , 一种是第一个元素内的值为 -1 , 一种是为 0, -1的版本在跳跃移动的时候更好理解一些 。

    两个穿匹配的代码示例:

    void kmp(){
        int i = 0, j = 0;
        while (i != lens && j != lenp){ 
            if (s[i] == p[j] || j == -1) { // p 所存的是主串
                i++;
                j++;
            }
            else j = next[j]; // 两个串相匹配,当不匹配时,模式串回跳 
                              // 当第一个字母都不匹配时,j 的值会被赋值为 -1
                              // 当 j 的值等于 模式串长度时,即证明已此时两个串已全部匹配
        }
    }
    

     举个小例子 :

      比如abababab 与 abab 匹配 , 他们上来就可以实现全部匹配 , 接下来 模式串的指针就可以移动到 j = 2 的位置  即 a , 会继续与主串相匹配 。

    上面的程序其实是 MP 的代码,它会有一个弊端,如 abcabcd,当第 6 个字母 c 不匹配时会跳到第 3 个字母 c ,其实这样是没有必要的

    MP中,P[Next[i]]可能会与P[i]相等,那么其实 还是无法与目标串匹配,在KMP中创建Next数组时,加入了,P[i]不同于P[Next[i]]的条件

    MP -> next

    void GetNext(char p[],int m){
    	int i=0,j=-1;
    	Next[0]=-1;
    	while(i<m){
    		if(j==-1||p[i]==p[j]){
    			i++;
    			j++;
    			Next[i]=j;
    		}
    		else{
    			j=Next[j];
    		}
    	}
    	//Next[m]=0  作用同上
    }

    KMP -> next

    void GetNext(char p[],int m){
    	int i=0,j=-1;
    	Next[0]=-1;
    	while(i<m){
    		if(j==-1||p[i]==p[j]){
    			i++;
    			j++;
    			if(p[i]==p[j]){
    				Next[i]=Next[j];
    			}
    			else{
    			    Next[i]=j;
    			}
    		}
    		else{
    			j=Next[j];
    		}
    	}
    	//Next[m]=0  作用同上
    }
    

      

    东北日出西边雨 道是无情却有情
  • 相关阅读:
    递归
    作业 3月24日
    生成器
    迭代器
    解决python print 字符串 编码报错现象 unencode
    模式匹配迅速入手——ahocorasick第三方数据库的使用
    删除oracle部分数据
    html_获取参数
    ahocorasick从安装到使用
    Java 遍历map的四种方法
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/7625311.html
Copyright © 2020-2023  润新知