一、串数据类型的定义
1.定义和存储结构
char str[]="abcdef";
typedef struct
{
char str[maxSize+1];
int length;
}Str;
typedef struct
{
char *ch;
int length;
}Str;
2.串的基本操作
int strassign(Str& str,char* ch)
{
if(str.ch)free(str.ch)
int len=0;
char *c=ch;
while(*c)
{
++len;
++c;
}
if(len==0)
{
str.ch=NULL;
str.length=0;
return 1;
}
else
{
str.ch=(char*)malloc(sizeof(char)*(len+1));
if(str.ch==NULL)return 0;
else
{
c=ch;
for(int i=0;i<=len;++i,++c)str.ch[i]=*c;
str.length=len;
return 1;
}
}
}
int strlength(Str str)
{
return str.length;
}
int strcompare(Str s1, Str s2)
{
for(int i;i<s1.length&&i<s2.length;++i)
{
if(s1.ch[i]!=s2.ch[i])return s1.ch[i]-s2.ch[i];
return s1.length-s2.length;
}
}
int concat(Str &str, Str str1, Str str2)
{
if(str.ch)
{
free(str.ch);
str.ch=NULL;
}
str.ch=(char*)malloc(sizeof(char)*(str1.length+str2.length+1));
if(str.ch==NULL)return 0;
int i=0;
while(i<str1.length)
{
str.ch[i]=str1.ch[i];
++i;
}
int j;
while(j<=str2.length)
{
str.ch[i+j]=str2.ch[j];
++j;
}
str.length=str1.length+str2.length;
return 1;
}
int substring(Str& substr, Str str, ingt pos,int len)
{
if(pos<0||pos>=str.length||len<0||len>str.length-pos)return 0;
if(substr.ch)
{
free(substr.ch);
substr.ch=NULL;
}
if(len==0)
{
substr.ch=NULL;
substr.length=0;
return 1;
}
else
{
substr.ch=(char*)malloc(sizeof(char)*(len+1));
int i=pos;
int j=0;
while(i<pos+len)
{
substr.ch[j]=str.ch[i];
++i;
++j;
}
substr.ch[j]='\0';
sunstr.length=len;
return 1;
}
}
int clearstring(Str& str)
{
if(str.ch)
{
free(str.ch);
str.ch=NULL;
}
str.length=0;
return 1;
}
二、串的模式匹配算法
1.简单模式匹配算法
//对一个串中的定位操作称为串的模式匹配
//其中串中字符存放在1-length的位置上
int index(Str str,Str substr)
{
int i=1,j=1,k=i;
while(i<=str.length&&j<=str.length)
{
if(str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
{
j=1;
i=++k;
}
}
if(j>substr.length)return k;
else return 0;
}
2.KMP算法
//思路:每当发生模式串不匹配的情况,先找出发生不匹配的字符pj,取其子串F=p1p2p3...Pj-1
//将模式串后移,使F最先发生前部(FL)和后部(FR)相重合的位置,即模式串后移的目标位置
//即j指向的F前后重合的子串的长度+1(FL和FR的长度加1),可以定义一个next[j]数组,取j=1~m
//m为模式串长度,表示模式串中第j个字符发生不匹配时,应从next[j]处的字符开始重新发生与主串比较
//求next数组:
//next[j]已知,t为当前F最长相等前后缀长度(即FL和FR的长度next[j]=t)
//当pj=pt,则next[j+1]=t+1;
//当pj!=pt,则t=next[t];
void getnext(Str substr, int next[])
{
int j=1,t=0;next[1]=0;
while(j<substr.length)
{
if(t==0||substr.ch[i]==substr.ch[t])next[++j]=++t;
else t=next[t];
}
}
//得到next数组之后,可以将简单算法改进成著名的KMP算法
int KMP(Str str, Str substr, int next[])
{
//假设从下标为1开始存储的字符
int i=1, j=1;
while(i<=str.length&&j<=substr.length)
{
if(j==0||str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else j=next[j];
}
if(j>substr.length)retrun i-substr.length;
else return 0;
}
3.KMP算法的改进
//当j=1时,nextva[j]=0,作为特殊标记
//pj!=pk时,nextval[j]=next[j]=k;
//pj=pk时,nextval[j]=nextval[next[j]]=nextval[k];
void getnextval(Str substr,int nextval[])
{
int i=1,j=0;
nextval[1]=0;
while(i<substr.length)
{
if(j==0||substr.ch[i]==substr.ch[j])
{
++i;
++j;
// 加了这两句
if(substr.ch[i]!=substr.ch[j])nextval[i]=j;
else nextval[i]=nextval[j];
}
else j=nextval[j];
}
}