KMP 算法

思路

image.png

image.png

image.png

Next数组

伪代码

public static int[] getNext(String ps) {
    char[] p = ps.toCharArray();
    int[] next = new int[p.length];
    next[0] = -1;
    int j = 0;
    int k = -1;
    while (j < p.length - 1) {
       if (k == -1 || p[j] == p[k]) {
           if (p[++j] == p[++k]) { // 当两个字符相等时要跳过
              next[j] = next[k];
           } else {
              next[j] = k;
           }
       } else {
           k = next[k];
       }
    }
    return next;
}

推导

  1. 当j=0时,
    j=0

    S[i]!=P[j],i应当右移一位,故\rm{next}[0]=-1
  2. k=-1时, 说明j的前串与p的前串无相同部分
    P[j+1]==P[0],则P[0]与S[i]也不相同,直接右移,\rm{next}[j+1]=-1
    P[j+1]!=P[0]\rm{next}[j+1]=0,判断P[0]与S[i]
  3. \rm{next}[j]=k应满足:
    P[0, k-1] == P[j-k,j-1]
    P[j]==P[k], P[0, k] == P[j-k, j]
    P[j+1]==P[k+1],则P[k+1]与S[i]也不相同,令\rm{next}[j+1] = \rm{next}[k+1]
    P[j+1]!=P[k+1],令\rm{next}[j+1]=k+1
  4. P[k] != P[j]时,
    P[k] != P[j]

    k = \rm{next}[k] 继续匹配

主算法

public static int KMP(String ts, String ps) {
    char[] t = ts.toCharArray();
    char[] p = ps.toCharArray();
    int i = 0; // 主串的位置
    int j = 0; // 模式串的位置
    int[] next = getNext(ps);
    while (i < t.length && j < p.length) {
       if (j == -1 || t[i] == p[j]) { // 当j为-1时,要移动的是i,当然j也要归0
           i++;
           j++;
       } else {
           // i不需要回溯了
           // i = i - j + 1;
           j = next[j]; // j回到指定位置
       }
    }
    if (j == p.length) {
       return i - j;
    } else {
       return -1;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 字符串匹配KMP算法详解 1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有...
    张晨辉Allen阅读 2,456评论 0 3
  • 文章大纲:1.KMP算法概念2.KMP算法中最核心的next[] 数组是如何生成的3.使用KMP算法 匹配字符串 ...
    柠檬乌冬面阅读 831评论 0 3
  • 这是我的平安果,送给你,祝妈妈平安快乐!收到小朋友送的礼物才发现都已经12月24日了,2018年仅剩下7天时间了。...
    玫瑰就是我阅读 173评论 0 1
  • 渐渐体会到GAN训练难确实是一个让人头疼的问题,一个多月前我曾粗略地了解了一下WGAN,知道这是一个着眼于提高GA...
    6e845d5ac37b阅读 24,418评论 2 19
  • 奶奶说,有钱了就可以去医院,看看老寒腿,治治关节炎。 爸爸说,有钱了就可以把家里的旧屋翻新,可以有财礼钱给二娃娶媳...
    时光恰巧阅读 345评论 0 5