kmp算法c++

打印 上一主题 下一主题

主题 573|帖子 573|积分 1723

kmp算法通过next数组使查找失败时减少跳转后比较的次数来优化字符串查找,next数组存储了前缀和后缀相同的位置信息,雷同动规,可以存储查找数组的信息来防止重复查找,最终复杂度可以达到O(n+m)。
以t=“abcabd”字符串为例进行讲解
next数组存储的是当前位置与前面具有相同前缀的长度,同时在查找失败后,可以在失败位置的其哪一个位置对应的next数组值来跳转到具有相同前缀的字符串的下一个位置,如许就可以制止重复验证前缀部门是否和被查找的字符串匹配。
具体的演示可以看和手算方法见「六分钟速通」KMP算法求解流程,up讲的简单明白。视频里pm即为文中的next数组
next里的数字代表包括t在内的部门与前面字符串部门子串相同的长度,同时该数字也是前面相同子串的下一个字符的下标。
这里设j,k作为下标表示,j为当前盘算的下标,k为前面与当前盘算下标j结尾的子串相同的子串的结尾下标,即具有相同前缀的子串结尾下标。
当k=0时,有两种情况,一是t[j]=t[k],那么此时next[j]=next[j-1]+1,即相同前缀部门变大,如果差别,此时k=0,则next[j]应该为0,即没有相同前缀。
当k!=0时,如果t[k]=t[j],则按上述盘算方法来表示扩大相同前缀,如果t[k]!=t[j],那么向前找相同前缀,做法时k=next[k-1],因为next数组存储的是当前位置与前面具有相同前缀的长度,则向前查找只必要找到以k-1结尾的相同子串的长度,如果还差别,重复向前查找,直到k=0或找到相同前缀为止。
  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. using namespace std;
  5. void grtnext(char *c, int *nextKMP)
  6. {
  7.     int len = strlen(c);
  8.     nextKMP[0] = 0;
  9.     int k = 0;
  10.     int j = 1;
  11.     while (j < len)
  12.     {
  13.         if (k == 0)
  14.         {
  15.             if (c[j] == c[k])
  16.             {
  17.                 nextKMP[j] = 1;
  18.                 k++;
  19.             }
  20.             else
  21.                 nextKMP[j] = 0;
  22.             j++;
  23.             continue;
  24.         }
  25.         if (c[j] == c[k])
  26.         {
  27.             nextKMP[j] = nextKMP[j - 1] + 1;
  28.             k++;
  29.             j++;
  30.         }
  31.         else
  32.         {
  33.             k = nextKMP[k - 1];
  34.         }
  35.     }
  36. }
  37. int KMP(char *s, char *t, int *next, int *re)
  38. {
  39.     int lens = strlen(s);
  40.     int lent = strlen(t);
  41.     int i = 0, j = 0;
  42.     while (i < lens && j < lent)
  43.     {
  44.         re[0]++;
  45.         if (s[i] == t[j])
  46.         {
  47.             i++;
  48.             j++;
  49.         }
  50.         else
  51.         {
  52.             if (j == 0)
  53.                 i++;
  54.             else
  55.                 j = next[j - 1];
  56.         }
  57.     }
  58.     if (j == lent)
  59.         return i - lent;
  60.     return -1;
  61. }
  62. int trlen(char *s)
  63. {
  64.     int len = 0;
  65.     while (s[len] != '\0')
  66.     {
  67.         len++;
  68.     }
  69. }
  70. int main()
  71. {
  72.     char *c = "aabaac";
  73.     char *s = "aabaabaaac";
  74.     int len = strlen(c);
  75.     int re[2] = {0};
  76.     int *nextKMP = new int[len];
  77.     grtnext(c, nextKMP);
  78.     int k = KMP(s, c, nextKMP, re);
  79.     // for (int i = 0; i < len; i++)
  80.     // {
  81.     //     cout << nextKMP[i] << " ";
  82.     // }
  83. if(k==-1)cout<<"no find"<<endl;
  84. else
  85.     cout << k + 1 << endl;
  86.     cout << re[0]; // 输出比较次数
  87.     system("pause");
  88. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表