Bootstrap

【C++KMP算法】

KMP算法:

KMP算法是一种改进的字符串匹配算法。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。–百度百科解释


算法过程:

1.算法分为两步,一步用于得到next数组,一步用于字符串比对
2.获得next数组时,类似于递推式的方式。先给出两个初始值next[0],next[1],然后计算i的next值时,在前一位置的基础上进行比较,比较成功则i位置的值直接加一。否则往前跳转,直到找到匹配值或者跳到首位置(next[i]=0)
3.对比时,相同则两个指针同时后移,若不同,则对照数组调到next数组中的位置继续进行比较,若一直调到首位置,则搜索数组指针向后移一位。

问题描述

参考左神代码编写:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

vector<int> get_next_array(vector<char> s_2)
{
    if (s_2.size() == 1)
    {
        vector<int> a = {-1};
        return a;
    }
    vector<int> next(s_2.size(), 0);
    next[0] = -1;
    next[1] = 0;
    int i = 2;    // next数组位置
    int comp = 0; //比较位置
    while (i < s_2.size())
    {
        if (s_2[i - 1] == s_2[comp]) //当前位前一位和对比位置是否相同
        {
            next[i++] = ++comp; //相同则第i位置前缀和为比较处最大前缀加一
        }
        else if (comp > 0)
        {
            comp = next[comp];
        }
        else
        {
            next[i++] = 0;
        }
    }
    return next;
}

//匹配成功时,返回s1中相同子串的头位置 匹配失败时,返回-1
int get_index(string s1, string s2)
{
    if (s1.length() < 0 || s2.length() < 0 || s1.length() < s2.length())
    {
        return -1;
    }
    vector<char> s_1;
    s_1.assign(s1.begin(), s1.end());
    vector<char> s_2;
    s_2.assign(s2.begin(), s2.end());
    int i = 0; // s1字符串比对位置
    int j = 0; // s2字符串比对位置
    vector<int> next = get_next_array(s_2);
    while (i < s_1.size() && j < s_2.size())
    {
        if (s_1[i] == s_2[j]) //比对相同,同时后移
        {
            ++i;
            ++j;
        }
        else if (next[j] = -1) //如果来到头位置,则原字符串移一位
        {
            ++i;
        }
        else
        {
            j = next[j]; // j未调到头位置时,往前跳
        }
    }
    //如果匹配成功,此时i,j指向相同位置的下一位置,i-j即为头位置
    return j == s_2.size() ? i - j : -1;
}

int main()
{
    string s1 = "abcdhcdedfg";
    string s2 = "cde";
    int index = get_index(s1, s2);
    cout << "字符串  " << s1 << "  和  " << s2 << endl
         << "相同子串首位置为:" << index << endl;
    return 0;
}

结果:

在这里插入图片描述

;