• KMP算法浅析


    具体参见: KMP算法详解

    背景

      KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字。其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除了指针i的回溯问题,只需确定下次匹配j的位置即可,使得问题的复杂度由O(mn)下降到O(m+n)

      KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。
      在KMP算法中,为了确定在匹配不成功时,下次匹配时j的位置,引入了next[]数组,next[j]的值表示P[0...j-1]中最长后缀的长度等于相同字符序列的前缀。
    对于next[]数组的定义如下:
      1) next[j]=-1  j=0
      2) next[j]=max k:0<k<j P[0...k-1]=P[j-k,j-1]
      3) next[j]=0  其他
    如:
      P      a    b   a    b   a
      j       0   1    2   3   4
      next -1  0    0   1   2
    即next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]

    next的求解程序如下:

      

     1 private int[] next(String str){
     2         if(str == null || str.length() == 0){
     3             return null ;
     4         }
     5         int [] next = new int [str.length()] ;
     6         next[0] = -1 ;
     7         int lastSame = 0 ;
     8         for(int i = 1 ; i < str.length() ; i++ ){
     9             char temp = str.charAt(i) ;
    10             next[i] = lastSame ;
    11             if(temp == str.charAt(lastSame)){                
    12                 lastSame++ ;
    13             }else{
    14                 lastSame = 0 ;
    15             }            
    16         }
    17         
    18         return next ;
    19     }

    通过next采用KMP算法判断是否匹配的代码如下:

     1 /**
     2      * 若src包含dest子串,则返回src中dest子串出现的位置(首字符的位置),
     3      * 若不包含,则返回-1
     4      * @param src
     5      * @param dest
     6      * @return
     7      */
     8     private int KMPmatch(String src, String dest){
     9         if(src == null || dest == null || src.length() < dest.length()){
    10             return -1 ;
    11         }
    12         int [] next = next(dest);
    13         int i = 0 ; 
    14         int j = 0 ;
    15         while(i < src.length()){
    16             if((j == -1) || (src.charAt(i) == dest.charAt(j))){
    17                 i++ ;
    18                 j++ ;
    19             }else{
    20                 j = next[j] ;
    21             }
    22             
    23             if(j == (dest.length())){
    24                 return i-j ;
    25             }
    26         }
    27         
    28         return -1 ;
    29     }


      

  • 相关阅读:
    【python】第一个爬虫:用requests库爬取网页内容
    【python】UDP协议编程
    【python】体育竞技分析:预测球队比赛成绩
    【python】手绘图制作
    【python】成绩表雷达图
    【python】numpy库和matplotlib库学习笔记
    【python】PIL库之图片处理
    【python】PIL库学习总结
    【python】利用jieba中文分词进行词频统计及生成词云
    汉诺塔问题
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/5658552.html
Copyright © 2020-2023  润新知