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
  • 相关阅读:
    【计算机网络】网络地址转换NAT
    红黑树
    引用和取地址区别
    [网络编程] TCP、UDP区别以及TCP传输原理、拥塞避免、连接建立、连接释放总结
    操作系统大端模式和小端模式
    点乘和叉乘
    HMM模型
    Application_Start
    跨函数使用内存空间
    框架
  • 原文地址:https://www.cnblogs.com/runnyu/p/5919268.html
Copyright © 2011-2022 走看看