zoukankan      html  css  js  c++  java
  • 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     }


      

  • 相关阅读:
    Centos7.6安装教程 && history设置显示执行命令的时间
    C# 调用第三方webapi 接口的示例(使用httpclient)
    asp.net core 上传文件
    Sql中CHARINDEX用法---判断数据库某个字段是否包含某个字符
    ASP.NET上传文件出现“404-找不到文件或目录”的解决办法
    C# 中转换的几种方式
    C# 向文件写入和读取文件内容
    C# 中正则表达式
    C# 写的通用得到富文本框中的图片路径
    C# 正则表达式输入验证必须为汉字
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/5658552.html
Copyright © 2011-2022 走看看