算法读书笔记第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;
}
