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

  暴力匹配法的思路为:

  如果用暴力匹配的思路,并假设现在文本串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]的目的是表示当前匹配的前缀长度。

 

  

posted on 2019-03-20 22:45  醉晚  阅读(161)  评论(0编辑  收藏  举报