题:
对于两个字符串A,B。请设计一个高效算法,找到B在A中第一次出现的起始位置。若B未在A中出现,则返回-1。
给定两个字符串A和B,及它们的长度lena和lenb,请返回题目所求的答案。
例:
“acbc”,4,”bc”,2
返回:2
思:
next数组的获取,当前位置为cur
cur-2位置结尾的某个字符串
与
字符串开头到preEnd-1位置是相等的字符串,
则只需匹配cur-1和preEnd是否相等
码:
vector<int> getNextArray(const string &str){
vector<int> next(str.size());
if(str.size()==0)
return next;
next[0]=-1;
if(str.size()==1)
return next;
next[1]=0;
int pos=2;//当前位置
int preEnd=0;//
while(pos<next.size()){
if(str[pos-1]==str[preEnd])//看前面位置
next[pos++]=++preEnd;
else if(preEnd>0)
preEnd=next[preEnd];
else
next[pos++]=0;
}
return next;
}
int findAppearance(string A, int lena, string B, int lenb) {
if(lenb==0)
return 0;
if(lenb<0||lena<0||lenb>lena)
return -1;
vector<int> next=getNextArray(B);
int j=0;
int i=0;
for(;i<lena&&j<lenb;){
int oldi=i;
if(A[i]==B[j]){
i++;
j++;
}else if(next[j]==-1){//已经匹配所有,只能跳过这个字符,j==0
i++;
}else
j=next[j];
}
return j==lenb?i-lenb:-1;
}
测:
int main(){
string strs="syyasyybcd";//-1,0,0,0,0,1,2,3,0,0
string strl="fdfasfdsfs"
"syyasyybcd"
"fasdfasfad";
cout<<findAppearance(strl,strl.size(),strs,strs.size());
return 0;
}