#include<iostream>
#include<cstring>
using namespace std;
#define MAXSTR 100
//----------------BF---------------- 时间o(n*m)
int StringMatch_BF(char *str, char *pat) //O(M*N) M=|str| , N=|pat|
{
if(str==NULL||pat==NULL) return -1;
int i=0,j=0,irec=0;
for(;;){
while(str[i]!='\0'&&pat[j]!='\0')
if(str[i]==pat[j]){
i++;
j++;
}
else{
i=++irec;
j=0;
break;
}
if(pat[j]=='\0') //找到匹配位置
return irec;
if(str[i]=='\0') //没有匹配位置
return -1;
}
}
//----------------BF----------------
//------------KMP-------------预处理子串,得到next数组,表示子串中的某个位置在跟主串不匹配时,应该继续跟主串匹配的下一个位置。
//时间o(n+m)摊还分析
void NextInit(int next[], char* pat)
{
next[0]=-1;
if(pat[1]=='\0')
return;
next[1]=0;
int pos=2,cnt=0;
while(pat[pos]!='\0'){
if(pat[pos-1]==pat[cnt]){
next[pos++]=++cnt;
}
else{
if(cnt>0)
cnt=next[cnt];
else
next[pos++]=0; //此时cnt==0
}
}
for(pos=1;pat[pos]!='\0';pos++) //改进next数组
if(pat[pos]==pat[next[pos]])//这种情况下可以直接重新开了
next[pos]=0; //如主串cbdcbc和cbdcbd不匹配时,要拿子串的开头c和主串的结尾c比较
}
int StringMatch_KMP(char *str, char *pat)
{
int next[MAXSTR];
NextInit(next,pat);
int i=0,j=0,irec=0;
while(str[i]!='\0'&&pat[j]!='\0')
if(str[i]!=pat[j]){
if(next[j]<0){
i++;
irec=i;
j=0;
}
else{
irec+=j-next[j];//原串的匹配初始位置也发生了变化
j=next[j];
}
}
else{
i++;
j++;
}
if(pat[j]=='\0')
return irec;
else
return -1;
}
//---------------KMP----------------------
//---------------其他匹配算法待补充,如后缀数组,自动机等----------------------
//------------字符串近似匹配-------------
int StringNearMatch(char *str, char*pat,int k,int &begin)
{
int EditDis[MAXSTR][MAXSTR];
int rec[MAXSTR][MAXSTR];
int i,j;
EditDis[0][0]=0;
for(i=0;str[i]!='\0';i++)
EditDis[i+1][0]=0;
for(i=0;pat[i]!='\0';i++)
EditDis[0][i+1]=i+1;
for(i=0;str[i]!='\0';i++)
for(j=0;pat[j]!='\0';j++)
if(str[i]==pat[j]){
EditDis[i+1][j+1]=EditDis[i][j];
rec[i+1][j+1]=0;
}
else
if(EditDis[i][j]>EditDis[i][j+1]){
EditDis[i+1][j+1]=EditDis[i][j+1]+1;
rec[i+1][j+1]=-1;
}
else{
if(EditDis[i][j]>EditDis[i+1][j]){
EditDis[i+1][j+1]=EditDis[i+1][j]+1;
rec[i+1][j+1]=1;
}
else{
EditDis[i+1][j+1]=EditDis[i][j]+1;
rec[i+1][j+1]=0;
}
}
//下面是找到第一个匹配模式串的地方,并返回末尾位置 ,begin返回初始位置
if(EditDis[0][j]<=k){//错误次数允许大于等于模式串的长度
begin = -1;
return -1;
}
for(i=0;str[i]!='\0';i++)
if(EditDis[i+1][j]<=k)
break;
if(str[i]=='\0') //找不到近似匹配的子串
return -2;
int tail=i;
i++;
while(i>0&&j>0&&EditDis[i][j]!=0)
switch(rec[i][j]){
case 0: i--;j--;break;
case -1: i--;break;
case 1: j--;break;
}
while(j!=0){ i--;j--; }
begin=i>=0?i:-1;//-1表明要在的前面加字符串才可
return tail;
}
//------------字符串近似匹配-----------------
int main()
{
loop:
char str1[MAXSTR],str2[MAXSTR];
cin>>str1>>str2;
//cout<<StringMatch_BF(str1,str2)<<endl;
//cout<<StringMatch_KMP(str1,str2)<<endl;
int begin,k;
cin>>k;
int tail=StringNearMatch(str1,str2,k,begin);
if(tail==-2){
cout<<"not find"<<endl;
goto loop;
}
cout<<begin<<" , "<<tail<<endl;
goto loop;
return 0;
}