数据结构之串
串
定义:由零个或多个字符组成的有限序列,又名叫字符串。
子串:串中任意个数的连续字符组成的子序列称为该串的子串。
Index的实现:
substring(Sub,S,pos,len)
//串S存在,1<=pos<=strlength(S),且0<=len<=strlength(S)-pos+1
//用sub返回S中第pos个字符起长度为len的子串
Index(S,T,pos)
//串S和T存在,T是非空串,1<=pos<=strlength(S),
//若主串S中存在和串T值相同的子串,则返回它在主串S中第pos个字符之后第一次出现的位置
int Index(string S,string T,int pos)
{
int m,n,i;
string sub;
if(pos>0)
{
n=strlen(S);
m=strlen(T);
i=pos;
while(i<n-m-1)
{
substring(sub,S,i,m);//取主串第i个位置,长度为m的子串,复制给sub
if(strcmp(sub,T)!=0)//若取出的子串sub与T不同时
{
++i;//继续往后走
}
else return i;//返回出现匹配成功的位置
}
}
return 0;//若没有匹配的子串,返回0
}
储存结构
顺序储存:数组储存
链式储存:链表储存
朴素的模式匹配算法
//朴素的模式匹配算法
int Index(string S,string T,int pos)
{
slen=strlength(S);//函数返回串长度
tlen=strlengtg(T);
int i=pos;//i是主串S的下标 n
int j=1;//j是子串T中的下标
while(i<=slen&&j<=tlen)//当i和j都没有走到串尾时
{
//判断当前字母是否相等
if(T[j]==S[i])//相等的话ij继续往下走
{
i++;
j++;
}
else //不相等的话i回到上一次匹配位置的下一位,j重新从第一位开始
{
i=i-j+2;//可画图观察,很好得出
j=1;
}
}
if(j>tlen)//已经完全遍历完T,即在S中找到了匹配的子串
return i-tlen;
//没找到
else return 0;
}
KMP模式匹配算法及其改进
朴素的模式匹配算法实在是笨重,所以我们学学别的算法----KMP模式匹配算法。
u1s1,kmp真的好难懂啊,我哭的很大声,看看书上的代码感觉跟朴素的模式匹配算法差不多,结果原理真的很难弄懂,苦涩,看书迷迷糊糊所以去了b站,只能说b站yyds, 传送门doge。
下面放了自己看完视频写的代码和一些注释,供大家参考…
//KMP模式匹配算法
//返回子串T中的next数组
void get_next(string T, int *next)//
{
int i=1;
int j=0;
next[1]=0;
while(i<strlength(T))//当i小于字符串T的长度时
{
if(j==0||T[i]==T[j])//当匹配成功或者T=0时
{
i++;
j++;
next[i]=j;//next[i+1]=next[j]+1
}
else
{
j=next[j];
}
}
}
int Index(string S,string T,int pos)
{
int i=pos;//i为主串当前的下标位置,从pos位开始匹配
int j=1;//j为当前子串的下标位置
next[300];//定义一个next数组
get_next(string T,next) ;//得到next表
while(i<=lenS&&j<=lenT)
{
if(j==0||S[i]==T[j])//匹配
{
i++;
j++;
}
else //失配
{
j=next[j];//j退回合适的位置,i不变
}
}
if(j>lenT)//返回子串在主串中的第一次出现的位置
{
return i-lenT;
}
else return 0;//未找到
}
KMP中get_next数组的改进,改进后的我们暂且叫nextval数组
void get_nextval(string T,int *nextval)
{
int i=1;
int j=0;
nextval[1]=0;
while(i<lenT)
{
if(j==0||T[i]==T[j])
{
i++;
j++;
if(T[i]!=T[j])
{
next[i]=j;
}
else
{
next[i]=next[j];
}
}
else j=next[j];
}
}