实现顺序串的各种模式匹配算法
函数操作
- 采用简单匹配算法求子串t在主串s中的位置
- 采用KMP算法求子串t在主串s中的位置
- 采用改进的KMP算法求子串t在主串s中的位置
代码实现
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MaxSize 100
typedef int Status;
typedef struct
{
char data[MaxSize];
int length;
}HString;
Status StrAssign(HString &T,char *chars);//生成一个其值等于串常量chars的串T
int StrLength(HString S);//返回S的元素个数,称为串的长度
int StrCompare(HString S, HString T);//若S>T,则返回值>0;若S=T,则返回值=0;若S<T则返回值<0
Status ClearString(HString &S);//将S清空
Status Concat(HString &T, HString S1, HString S2);//用T返回由S1和S2联接而成的新串
Status SubString(HString &Sub, HString S, int pos, int len);
//用Sub返回串S的第pos个字符起长度为len的子串。
int Index_BF(HString S, HString T, int pos);//朴素模式匹配算法
// 返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0。
Status StrInsert(HString &S,int pos,HString T);//在串S的第pos个字符之前插入串T。
Status StrDelete(HString &S,int pos,int len);//从串S中删除第pos个字符起长度为len的子串
void DispStr(HString s);
void GetNextval(HString t,int nextval[]);//求出nextval值
int KMPIndex1(HString s,HString t);//修正的KMP算法
Status StrAssign(HString &T,char *chars)//生成一个其值等于串常量chars的串T
{
int i=0;
for(;chars[i]!='\0';i++)
{
T.data[i]=chars[i];
}
T.length=i;
return true;
}
int StrLength(HString S)//返回S的元素个数,称为串的长度
{
return S.length;
}
int StrCompare(HString S, HString T)//若S>T,则返回值>0;若S=T,则返回值=0;若S<T则返回值<0
{
return S.length-T.length;
}
Status ClearString(HString &S)//将S清空
{
S.length=0;return true;
}
Status Concat(HString &T, HString S1, HString S2)//用T返回由S1和S2联接而成的新串
{
int i=0,j=0;
for(;i<S1.length;i++)
T.data[i]=S1.data[i];
for(j=0;j<S2.length;j++)
T.data[i+j]=S2.data[j];
T.length=S1.length+S2.length;
return true;
}
Status SubString(HString &Sub, HString S, int pos, int len)//用Sub返回串S的第pos个字符起长度为len的子串
{
int i,j=0;
for(i=pos-1;i<pos+len-1;i++,j++)
Sub.data[j]=S.data[i];
Sub.length=len;
return true;
}
int Index_BF(HString S, HString T, int pos)//朴素模式匹配算法
// 返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0。
{
int i,j,sum=0;
for(i=pos;i<S.length;i++)
{
sum=0;
for(j=0;j<T.length;j++)
{
if(S.data[i+j]!=T.data[j])
break;
if(S.data[i+j]==T.data[j])
sum++;
if(sum>=T.length)
return i+1;//返回主串的匹配首字符的位置
}
}
return 0;
}
int Index_BF(HString S, HString T)//朴素模式匹配算法
// 返回子串T在主串S中的位置,若不存在,则函数值为0。
{
int i,j,sum=0;
for(i=0;i<S.length;i++)
{
sum=0;
for(j=0;j<T.length;j++)
{
if(S.data[i+j]!=T.data[j])
break;
if(S.data[i+j]==T.data[j])
sum++;
}
if(sum>=T.length)
return i+1;//返回主串的匹配首字符的位置
}
return 0;
}
Status StrInsert(HString &S,int pos,HString T)//在串S的第pos个字符之前插入串T。
{
int j;
HString str;
str.length=0;
if(pos<=0||pos>S.length+1) return 0;//参数不正确,返回空串
for(j=0;j<pos-1;j++)//将S.data[0...i-2]复制到str
str.data[j]=S.data[j];
for(j=0;j<T.length;j++)//将S.data[0....s2.length-1]复制到str
str.data[pos+j-1]=T.data[j];
for(j=pos-1;j<S.length;j++)//将S.data[i-1...s1.length-1]复制到str
str.data[T.length+j]=S.data[j];
str.length=S.length+T.length;
S=str;
return 1;
}
Status StrDelete(HString &S,int pos,int len)//从串S中删除第pos个字符起长度为len的子串
{
int i;
HString str;
for(i=0;i<pos-1;i++)
str.data[i]=S.data[i];
for(;i<S.length-len;i++)
str.data[i]=S.data[i+len];
str.length=S.length-len;
S=str;
return true;
}
void DispStr(HString s)
{
int i;
if(s.length>0)
{
for(i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
}
void GetNext(HString t,int next[])
{
int j,k;
j=0;k=-1;next[0]=-1;
while(j<t.length-1)
{
if(k==-1||t.data[j]==t.data[k])
{
j++;k++;
next[j]=k;
}
else k=next[k];
}
}
int KMPIndex(HString s,HString t)
{
int next[MaxSize],i=0,j=0;
GetNext(t,next);
while(i<s.length&&j<t.length)
{
if(j==-1||s.data[i]==t.data[j])
{
i++;
j++;
}
else j=next[j];
}
if(j>=t.length)
return (i-t.length+1);//返回主串的匹配首字符的位置
else
return (-1);
}
void GetNextval(HString t,int nextval[])
{//求出nextval值
int j=0,k=-1;
nextval[0]=-1;
while(j<t.length)
{
if(k==-1||t.data[j]==t.data[k])
{
j++;k++;
if(t.data[j]!=t.data[k])
nextval[j]=k;
else
nextval[j]=nextval[k];
}
else
k=nextval[k];
}
}
int KMPIndex1(HString s,HString t)
{//修正的KMP算法
int nextval[MaxSize],i=0,j=0;
GetNextval(t,nextval);
while(i<s.length&&j<t.length)
{
if(j==-1||s.data[i]==t.data[j])
{
i++;
j++;
}
else
j=nextval[j];
}
if(j>=t.length)
return (i-t.length+1);
else
return (-1);
}
int main()
{
HString S,T,Sub;
StrAssign(S,"abcdefgcdeklmnopqrstuvwxyz");//创造一个主串
printf("S:");
DispStr(S);
printf("S串的长度为%d\n",StrLength(S));
StrAssign(T,"cde");//创造一个模式串
printf("T:");
DispStr(T);
printf("使用BF算法\n");
printf("Index_BF(S,T)>>返回子串T在主串S中的位置,位置为%d\n",Index_BF(S,T));// 返回子串T在主串sS中的位置,若不存在,则函数值为0
printf("使用BF算法\n");
printf("Index_BF(S,T,4)>>返回子串T在主串S中第pos个字符之后的位置,在主串中的位置为%d\n",Index_BF(S,T,4));// 返回子串T在主串sS中第pos个字符之后的位置,若不存在,则函数值为0
printf("使用KMF算法\n");
printf("KMPIndex(S,T)>>返回子串T在主串S中的位置,位置为%d\n",KMPIndex(S,T));
printf("使用改进的KMP算法\n");
printf("KMPIndex1(S,T)>>返回子串T在主串S中的位置,位置为%d\n",KMPIndex1(S,T));
}
输出