kmp算法浅析

解释不对的地方 希望帮忙指出来我们一起探讨 

1.kmp算法的原理:
  本部分内容转自:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

2.next数组 即是找搜索词在 k属于[0,搜索词长-1] 位置时 前缀与后缀的最长公共子串(连续)
例如 :字符串 “ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA,],后缀为[BCDAB, CDAB, DAB, AB, B],”AB”作为他们的最长公共子串 长度为2 。

*前缀起点相对稳定 后缀起点不断变化****

void create_next(string str2 , int *next )
{
  // ############Create next##################
    unsigned int i = 0;
    unsigned int j = 1;
    next[0] = 0;
    while(j < str2.size())
    {
        if(str2[i] == str2[j])
        {
            i++;
            next[j] = i;//如果先j++就会跳过比较的那个字符str2[j]
            j++;
        }
        else
        {
            i=next[i];//i会一步一步回退
            j++;
        }

    }
}

3.判断字符串是否匹配: i 为源字符串下标 j 为搜索词字符串下标
(1)如果str1[i] != str2[j] 则下标 j 需要回退 (如果一直不相等 就会根据next数组一直回退 直到回退到0)
(2)如果相等 那么 j++
(3)如果j = str2.size() 代表已经越界了 而str1还没有退出 则匹配完毕
(1)(2)(3)的每一步 i 都需要向后移动

bool is_str_exist(string str1 , string str2 ,int *next)
{
for(int i = 0 , j = 0 ; i < str1.size()  ; i++)//控制字符串源
    {
            while(j > 0 && str1[i] != str2[j])
                j = next[j-1];     //一步一步根据next数组往回跳
            if(str1[i] == str2[j])
            {
                j++;
            }
          if(j == str2.size())//如果j已经越界了
            {
                return 1;
            }

    }
    return 0;

}

  **********完整程序**********
  

#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool isstrexist(string str1 , string str2)
{
  // ############Create next###################
    vector<int>next(str2.size(),0);//
    unsigned int i = 0;
    unsigned int j = 1;
    next[0] = 0;
    while(j < str2.size())
    {
        if(str2[i] == str2[j])
        {
            i++;
            next[j] = i;//如果先j++就会跳过比较的那个字符str2[j]
            j++;
        }
        else
        {
            i=next[i];//i回一步一步回退
            j++;
        }

    }

    for(auto i : next)
        cout<<i<<" ";
    cout<<endl;
    //####################test exist########################

    for(int i = 0 , j = 0 ; i < str1.size()  ; i++)//控制字符串源
    {
            while(j > 0 && str1[i] != str2[j])
                j = next[j-1];      //一步一步根据next数组往回跳
            if(str1[i] == str2[j])
            {

                j++;
            }
          if(j == str2.size())//如果j已经越界了
            {
                return 1;
            }

    }

    return 0;

}
int main()
{
    string str1 = "BBCABCDABABCD ABCDABDE";
    string str2 = "ABCDA";
    if(isstrexist(str1,str2))
       cout<<"exist"<<endl;
        cout<<str2<<endl;
    return 0;
}

谢谢

点赞