kmp算法
参考 https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg
字符串传参:https://www.cnblogs.com/shierlou-123/p/13554991.html
字符串匹配暴力算法:
void bruteforce(char *a,char *b){
for(int i=0;i<=strlen(a)-strlen(b);i++){
int flag=1;
for(int j=0;b[j]!='\0';j++){
if(a[i+j]!=b[j]){
flag=0;
break;
}
}
if(flag) cout<<i<<endl;
}
}
前缀表(不减一)=next数组:
void getnext(int *nxt,string &s){
int j=0;//j表示前缀起始位置
nxt[0]=0;
for(int i=1;i<s.size();i++){//i表示后缀起始位置,故从1开始
while(j>0 && s[i]!=s[j]){//前后缀出现不相同
j=nxt[j-1];//j往前回退
}
if(s[i]==s[j]){//找到相同的前后缀
j++;//继续往后匹配
}
nxt[i]=j;//将前缀的长度j赋给数组
}
}
int kmp(string maj,string pat){//major主串,pattern模式串
if(pat.size()==0){
return 0;
}
int next[pat.size()];
getnext(next,pat);
int j=0;//j表示模式串的下标
for(int i=0;i<maj.size();i++){
while(j>0 && maj[i]!=pat[j]){
j=next[j-1];//模式串可以直接从下标j开始匹配
}
if(maj[i]==pat[j]){
j++;//i和j同时向后移动
}
if(j==pat.size()){//说明maj中包含pat
return (i-pat.size()+1);//返回pat第一个元素在maj的位置
}
}
return -1;
}