408之数据结构与算法——4.串
合群是为了自保,孤独才是真正的自由。
1. 串的存储结构
1.0 概念
串:由0个或者多个字符组成的有限序列。
串中的字符个数n称为串的长度,n=0时的串为空串。
1.1 顺序存储
1.2 链式存储
2. 朴素模式匹配算法
2.0 概念
主串: 待匹配的串
子串: 主串的一部分,一定能在主串中找到
模式串: 不一定能在主串中找到
朴素模式匹配算法: 将主串中所有长度为m的子串依次与模式串进行对比,直到找到一个完全匹配的子串,或者所有子串都不匹配为止。(暴力匹配)
若主串长度为n,模式串长度为m。最坏时间复杂度为:O(nm)
2.1 代码实现
#include<iostream>
using namespace std;
#include<string>
int NaivePatternMatching(string str,string s){
for(int i=0,j=0;i<str.length() && j<=s.length();i++,j++){
if(j==s.length()) return i-j;
else{
if (str[i]==s[j]) continue;
else{
j=-1;
i=i-j;
}
}
}
return -1;
}
int main(){
string str="ababbabaababaada";
string s="ababa";
cout<<NaivePatternMatching(str,s);// 8
}
3. KMP算法
3.1 求Next数组
-
方法一:
-
方法二:
3.2 KMP算法
4. KMP的优化算法
4.0 概念
其本质只是在原有的kmp算法上,更新了Nextval数组,使算法优化。
4.1 求Nextval数组
5. KMP代码
#include<iostream>
using namespace std;
#include<string>
void NextArray(string s,int* next){
next[0]=0;
next[1]=1;
int i=1,j=1;
while(i<s.length()-1){
if(j==0 || s[i]==s[j-1])
next[++i]=++j;
else
j=next[j-1];
}
}
void NextvalArray(string s,int *next){
NextArray(s,next);
for(int i=1;i<s.length();i++)
if(s[i]==s[next[i]-1])
next[i]=next[next[i]-1];
}
int KMP(string str,string s){
int nextval[s.length()];
NextvalArray(s,nextval);
for(int i=0;i<s.length();i++)
cout<<nextval[i]<<'\t';
int i=0,j=0;
for(;i<str.length() && j<s.length(); i++,j++){
if(str[i]==s[j]) continue;
if(j==0) j--;
else{
i--;
j=nextval[j]-2;
}
}
if(j==s.length()) return i-j;
else return -1;
}
int main(){
string str="adabaababaabcacc";
string a="ababaa"; // next:011234 nextval=010104 locate=5
// string a="abaabcac"; // next:01122312 nextval=01021302 locate=7
cout<<"模式串串在主串中的位置:"<<KMP(str,a);
}