串的模式匹配:::实现子串在主串中的位置
一、BF算法
最重要的就是在求nxt数组中如果当前位置不成功
主串的位置如果回到相应的位置 i=i-j+1;;
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1];
int length;
}SString;
//pos==1 返回模式T 在主串中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
// 其中、T非空,1<=pos<=S.length 从第pos个位置开始查找
int Index_BF(SString S,SString T,int pos)
{
int i=pos,j=1;
while(i<=S.length&&j<=T.length)
{
if(S.ch[i]==T.ch[j]) {i++;j++;}
else {i=i-j+2;j=1;}//i==i-(j-1)+1;
}
if(j>T.length) return i-T.length;
else return 0;
}
int main()
{
// 这是定义的char[]字符数组
// getline(cin,str);//输入许多字符串 中间有空格
// cin>>str+1;
// 如果用string s;
// 不能用cin>>s+1;
// 可以用scanf("%s" ,s.c_str());
SString S,T;
int pos;
printf("请输入主串S的字符串:");
cin>>S.ch+1;
printf("请输入主串S的长度:");
cin>>S.length;
printf("请输入子串T的字符串:");
cin>>T.ch+1;
printf("请输入子串T的长度:");
cin>>T.length;
printf("请输入子串开始匹配的位置:");
cin>>pos;
if(Index_BF(S,T,pos))
{
printf("匹配成功!\n");
printf("相匹配的子串中的第一个字符在主串S中出现的位置:%d\n",Index_BF(S,T,pos));
}
else
{
puts("匹配失败!");
printf("未找到子串在主串中所出现的位置!\n");
}
return 0;
}
二、KMP算法
最重要的是计算nxt数组
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLEN 255
typedef struct{
char ch[MAXLEN+1];
int length;
}SString;
int nxt[MAXLEN];
void get_nxt(SString T,int nxt[])
{
int i=1,j=0;
nxt[1]=0;
while(i<T.length)
{
if(j==0||T.ch[i]==T.ch[j]) {++i;++j;nxt[i]=j;}
else j=nxt[j];
}
}
int Index_KMP(SString S,SString T,int pos)
{
int i=pos,j=1;
while(i<=S.length&&j<=T.length)
{
if(j==0||S.ch[i]==T.ch[j]) {i++;j++;}
else j=nxt[j];
}
if(j>T.length) return i-T.length;
else return 0;
}
int main()
{
SString S,T;
int pos;
get_nxt(T,nxt);
printf("请输入主串S的字符串:");
cin>>S.ch+1;
printf("请输入主串S的长度:");
cin>>S.length;
printf("请输入子串T的字符串:");
cin>>T.ch+1;
printf("请输入子串T的长度:");
cin>>T.length;
printf("请输入子串开始匹配的位置:");
cin>>pos;
if(Index_KMP(S,T,pos))
{
printf("匹配成功!\n");
printf("相匹配的子串中的第一个字符在主串S中出现的位置:%d\n",Index_KMP(S,T,pos));
}
else
{
puts("匹配失败!");
printf("未找到子串在主串中所出现的位置!\n");
}
return 0;
}
三、KMP算法中的nxt数组的升级
nxt的数组升级之后,为了让查找的次数更快,省去重复的查找
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLEN 1000
typedef struct{
char ch[MAXLEN+1];
int length;
}SString;
int nxt[MAXLEN];
void get_nxt(SString T,int nxt[])
{
int i=1,j=0;
nxt[1]=0;
while(i<T.length)
{
if(j==0||T.ch[i]==T.ch[j])
{
i++;j++;
if(T.ch[i]!=T.ch[j]) nxt[i]=j;
else nxt[i]=nxt[j];
}
else
j=nxt[j];
}
}
int Index_KMP(SString S,SString T,int pos)
{
int i=pos,j=1;
while(i<=S.length&&j<=T.length)
{
if(j==0||S.ch[i]==T.ch[j]) {i++;j++;}
else j=nxt[j];
}
if(j>T.length) return i-T.length;
else return 0;
}
int main()
{
SString S,T;
int pos;
printf("请输入主串S的字符串:");
cin>>S.ch+1;
printf("请输入主串S的长度:");
cin>>S.length;
printf("请输入子串T的字符串:");
cin>>T.ch+1;
printf("请输入子串T的长度:");
cin>>T.length;
printf("请输入子串开始匹配的位置:");
cin>>pos;
get_nxt(T,nxt);
if(Index_KMP(S,T,pos))
{
printf("匹配成功!\n");
printf("相匹配的子串中的第一个字符在主串S中出现的位置:%d\n",Index_KMP(S,T,pos));
}
else
{
puts("匹配失败!");
printf("未找到子串在主串中所出现的位置!\n");
}
return 0;
}