东湖之滨 发表于 2024-6-11 13:16:03

kmp算法c++

kmp算法通过next数组使查找失败时减少跳转后比较的次数来优化字符串查找,next数组存储了前缀和后缀相同的位置信息,雷同动规,可以存储查找数组的信息来防止重复查找,最终复杂度可以达到O(n+m)。
以t=“abcabd”字符串为例进行讲解
next数组存储的是当前位置与前面具有相同前缀的长度,同时在查找失败后,可以在失败位置的其哪一个位置对应的next数组值来跳转到具有相同前缀的字符串的下一个位置,如许就可以制止重复验证前缀部门是否和被查找的字符串匹配。
具体的演示可以看和手算方法见「六分钟速通」KMP算法求解流程,up讲的简单明白。视频里pm即为文中的next数组
next里的数字代表包括t在内的部门与前面字符串部门子串相同的长度,同时该数字也是前面相同子串的下一个字符的下标。
这里设j,k作为下标表示,j为当前盘算的下标,k为前面与当前盘算下标j结尾的子串相同的子串的结尾下标,即具有相同前缀的子串结尾下标。
当k=0时,有两种情况,一是t=t,那么此时next=next+1,即相同前缀部门变大,如果差别,此时k=0,则next应该为0,即没有相同前缀。
当k!=0时,如果t=t,则按上述盘算方法来表示扩大相同前缀,如果t!=t,那么向前找相同前缀,做法时k=next,因为next数组存储的是当前位置与前面具有相同前缀的长度,则向前查找只必要找到以k-1结尾的相同子串的长度,如果还差别,重复向前查找,直到k=0或找到相同前缀为止。
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;

void grtnext(char *c, int *nextKMP)
{
    int len = strlen(c);

    nextKMP = 0;
    int k = 0;
    int j = 1;
    while (j < len)
    {
      if (k == 0)
      {
            if (c == c)
            {
                nextKMP = 1;
                k++;
            }
            else
                nextKMP = 0;
            j++;
            continue;
      }
      if (c == c)
      {
            nextKMP = nextKMP + 1;
            k++;
            j++;
      }
      else
      {
            k = nextKMP;
      }
    }
}
int KMP(char *s, char *t, int *next, int *re)
{
    int lens = strlen(s);
    int lent = strlen(t);
    int i = 0, j = 0;

    while (i < lens && j < lent)
    {
      re++;
      if (s == t)
      {
            i++;
            j++;
      }
      else
      {
            if (j == 0)
                i++;
            else
                j = next;
      }
    }
    if (j == lent)
      return i - lent;
    return -1;
}
int trlen(char *s)
{
    int len = 0;
    while (s != '\0')
    {
      len++;
    }
}
int main()
{
    char *c = "aabaac";
    char *s = "aabaabaaac";
    int len = strlen(c);
    int re = {0};
    int *nextKMP = new int;
    grtnext(c, nextKMP);
    int k = KMP(s, c, nextKMP, re);
    // for (int i = 0; i < len; i++)
    // {
    //   cout << nextKMP << " ";
    // }
if(k==-1)cout<<"no find"<<endl;
else
    cout << k + 1 << endl;
    cout << re; // 输出比较次数
    system("pause");
}


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