算法读书笔记第5章

这一章我主要学习了kmp算法。
一、
kmp算法:用于求子串在主串中的起始位置。
例如:主串str1 = “ABC1abcabc23” str2 = “abcabc” 则
二、解题方法:
1、暴力匹配,时间复杂度O(n*m) n和m是两个字符串的长度
2、kmp,时间复杂度降为O(n),优化主要是在子串str2上,产生一个next数组
3、原理:代码中都有具体的标注用于理解,其实实现还是比较简单的
代码:
/**
    Name:  KMP
    Author: Bryant_xw
    Date: 2018-11-28-15.25.30
*/

/**
    查找子串在主串中出现的位置
    str1:abcabcababaccc
    str2:ababa
    返回POS = 6
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std;

//获取next数组
vector<int> getNextArr(char str2[]){
    int len = strlen(str2);
    vector<int> next(len);
       //人为规定子串的第1个、第2个next数组的值是-1和0
     next[0] = -1;
    next[1] = 0;
    int i = 2;
    int cn = 0;
    while(i < next.size()){
        if(str2[i-1] == str2[cn]){
            next[i++] = ++cn;
        }else if(cn > 0){
            cn = next[cn]; //回溯
        }else{
            next[i++] = 0;
        }
    }
    return next;
}

//获取Index
int KmpGetIndex(char str1[], char str2[]){
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    cout<<"len1:"<<len1<< " "<<str1<<endl;
    cout<<"len2:"<<len2<< " "<<str2<<endl;
    if(len2 > len1 || len2 < 1)
        return -1;
    int i = 0;
    int j = 0;
    vector<int> next = getNextArr(str2);
    while(i < len1 && j < len2)
    {
        if(str1[i] == str2[j]){
            i++, j++;
        }else if(next[j] == -1){
            i++;
        }else {
            j = next[j];
        }
    }
    return j == len2 ? i - j : -1;
}

int main()
{
    char s1[] = "abcabcababaccc";
    char s2[] = "ababa";
    cout << "Match pos is: "<< KmpGetIndex(s1,s2) << endl;
    return 0;
}


#笔记##读书笔记#
全部评论
摩拜神仙
点赞 回复
分享
发布于 2020-11-25 10:50

相关推荐

点赞 2 评论
分享
牛客网
牛客企业服务