zoukankan      html  css  js  c++  java
  • kmp算法

    相比于暴力的字串匹配算法,kmp算法在当前不匹配的情况下不会直接退回subStr[0]再重新匹配。

    网上盗两张图:

    假设i是src串中当前匹配的索引,j是sub串中当前匹配的索引。

    则在src[i] != sub[j]时,kmp算法会保持i不变,然后j指向相应的位置。

    观察上图可以看出,这个位置应该是sub[0, j - 1](即ABCDAB)中的最长相同前后缀:

    即ABCDAB最长前后缀为AB,容易证明只有在这个位置才可以进行最大匹配(前后缀相同)。

    具体算法实现如下(next数组就是sub[0, j - 1]的最长前后缀字符数):

     1 int kmpSearch(char* str, char* sub, int next[])
     2 {
     3     int i = 0, j = 0;
     4     int tLen = strlen(str);
     5     int sLen = strlen(sub);
     6     while (i < tLen && j < sLen)
     7     {
     8         // j == -1 第一个不匹配的时候(j = next[0])
     9         // 匹配的时候i、j向后移一位
    10         if (j == -1 || str[i] == sub[j])
    11         {
    12             ++i;
    13             ++j;
    14         }
    15         // 不匹配的时候i不变,j退回next[j]
    16         else
    17         {
    18             j = next[j];
    19         }
    20     }
    21     if (j == sLen)
    22         return i - j;
    23     return -1;
    24 }
    View Code

    next数组可以递归的求得

     1 void getNext(char* sub, int next[])
     2 {
     3     int len = strlen(sub);
     4     next[0] = -1;
     5     int j = 0, k = -1;
     6     while (j < len - 1)
     7     {
     8         if (k == -1 || sub[j] == sub[k])
     9         {
    10             ++k;
    11             ++j;
    12             next[j] = k;
    13         }
    14         else
    15         {
    16             k = next[k];
    17         }
    18     }
    19 }
    View Code
  • 相关阅读:
    Redis设置生存时间或过期时间的相关命令
    .Net Core使用Redis
    Redis的数据类型
    Java集合 使用Collections
    Java集合 使用Iterator
    Java集合 使用Stack
    响应式常用样式汇总
    图片 文字 背景等响应式设置总结
    微信动态聊天工具
    第2章 栅格系统
  • 原文地址:https://www.cnblogs.com/runnyu/p/5919268.html
Copyright © 2011-2022 走看看