• KMP算法


        字符串匹配可以采用暴力匹配法

      暴力匹配法的思路为:

      如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:

    1. 如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;
    2. 如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0。

       当然时间复杂度更低是所谓的KMP算法,该算法时间复杂度为O(m+n),空间复杂度为O(n)。

       m为被匹配的串的长度,n为进行匹配的模式串的长度。

         以下说明KMP算法的思路:

      假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
        1.如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
        2.如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。

      next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果next [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀后缀。

         此也意味着在某个字符失配时,该字符对应的next 值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到next [j] 的位置)。如果next [j] 等于0或-1,则跳到模式串的开头字符,若next [j] = k 且 k > 0,代表下次匹配跳到j 之前的某个字符,而不是跳到开头,且具体跳过了k 个字符。

      KMP代码实现为:

     1 int KmpSearch(char* s, char* p)
     2 {
     3     int i = 0;
     4     int j = 0;
     5     int sLen = strlen(s);
     6     int pLen = strlen(p);
     7     while (i < sLen && j < pLen)
     8     {
     9         //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++    
    10         if (j == -1 || s[i] == p[j])
    11         {
    12             i++;
    13             j++;
    14         }
    15         else
    16         {
    17             //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]    
    18             //next[j]即为j所对应的next值      
    19             j = next[j];
    20         }
    21     }
    22     if (j == pLen)
    23         return i - j;
    24     else
    25         return -1;
    26 }

      

      接下来对模式串生成的next数组进行讲解:

     1 void GetNext(char* p,int next[])
     2 {
     3     int pLen = strlen(p);
     4     next[0] = -1;
     5     int k = -1;
     6     int j = 0;
     7     while (j < pLen - 1)
     8     {
     9         //p[k]表示前缀,p[j]表示后缀
    10         if (k == -1 || p[j] == p[k]) 
    11         {
    12             ++k;
    13             ++j;
    14             next[j] = k;
    15         }
    16         else 
    17         {
    18             k = next[k];
    19         }
    20     }
    21 }

      在此只重点解释line 18处的next[k]=k;这处困扰了我很久,若想详细了解next数组产生过程,参照以下链接,讲解的特别清晰。

      https://blog.csdn.net/v_july_v/article/details/7041827

      next[k]=k解析:

      即寻找更小的子串,用next[k]的目的是表示当前匹配的前缀长度。

      

  • 相关阅读:
    多层装饰器执行顺序
    flask之 中间件 蓝图 falsk请求上下文 rquirements.txt threading.local 偏函数
    flask 之 在flask中使用websocket
    flask 之项目分文件使用sqlalchemy+flask-migrate djagno多数据库
    flask之六 sqlachemy详解 scoped_session线程安全 基本增删改查 多对多关系建立和操作 flask-sqlalchemy的使用
    远程连接linux开发项目
    INT104-lab9
    INT104-lab8
    INT104-lab7
    Java-数据结构-泛型BST-CPT102-tutorial Week6
  • 原文地址:https://www.cnblogs.com/wangshi2019/p/10568350.html
Copyright © 2020-2023  润新知