- 结构体定义、 串的基本操作 、模式匹配算法
一、结构体定义
//定长顺序存储表示结构体定义
typedef struct
{
char str[maxSize+1]; //maxSize为已经定义的常量表示串的最大长度
int length;
}Str;
//变长分配存储表示(又叫动态分配存储方法)
typedef struct
{
char *ch; // 指向动态分配存储区首地址的字符指针
int length; //串长度
}Str;
二、串的基本操作
赋值操作、取串长度操作、串比较操作、串连接操作、求子串、串清空
//串的基本操作
//赋值操作,将一个常量字符串赋给str,操作成功返回1,否则返回0
int strassign(Str& str,char *ch)
{
if(str.ch)
free(str.ch); //释放原串空间
int len=0;
char *c=ch;
while(*c) //求ch串的长度
{
++len;
++c;
}
if(len==0) //如果ch为空串,则直接返回空串
{
str.ch=NULL;
str.length=0;
return 1;
}
else
{
str.ch=(char*)malloc(sizeof(char)*(len+1));
//去len+1是为了多分配一个空间存放“\0”字符
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=0;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=0;
while(j<=str2.length)
//"<="
{
str.ch[i+j]=str.ch[j];
++j;
}
str.length=str1.length+str2.length;
return 1;
}
//求子串 从给定串中某一位置开始到某一位置结束
//在str串中从pos位置开始,长度为len的子串,子串由substr返回
int substring(Str & substr,Str str,int pos,int len)
{
if(pos<0||pos>=str.length||len<0||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';
substr.length=len;
return 1;
}
}
//串清空操作
int clearstring(Str &str)
{
if(str.ch)
{
free(str.ch);
str.ch=NULL;
}
str.length=0;
return 1;
}
三、模式匹配算法
BF算法和KMP算法
KMP算法原理参考链接:
https://blog.csdn.net/v_JULY_v/article/details/7041827
https://www.zhihu.com/question/34623343/answer/352148154
https://blog.csdn.net/buppt/article/details/78531384
BF算法
//串的模式匹配算法 BF算法
//若匹配成功,则返回模式串在主串中的位置,
//若不成功,则返回一个区别于主串所有位置的标记,如“0”
int index(Str str, Str substr)
{
int i=1,j=1,k=i;
while(i<=str.length&&j<=substr.length)
{
if(str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
{
j=1;
i=++k; //匹配失败,i从主串的下一个位置开始,k中记录了上一次的其实位置
}
}
if(j>substr.length)
return k;
else return 0;
}
KMP算法
//KMP算法
void getnext(Str substr,int next[])
{ //求模式串 substr 的next值并存入数组next
int i=1,j=0;
next[1]=0; //substr的第一个字符和主串失配时,主串的下一个字符与substr的第一个字符比较
while(i<substr.length) //当substr.length>1时,next[2]=1
{
if(j==0||substr.ch[i]==substr.ch[j]) //初态或两字符相等
{
++i; //各加1继续向后比较
++j;
next[i]=j;
//主串和substr在第i个字符不匹配时,前j-1个是匹配的,只需与第j个字符比较
}
else //两字符不等
j=next[j]; //j减小到前面字符相等之处
}
}
int KMP(Str str,Str substr,int next[])
{
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) //匹配成功
return i-substr.length;
else
return 0;
}
void GetNext(char * p, int next[])
{
next[0] = -1;
int i = 0, j = -1;
while (i < strlen(p)-1) //注意减1
{
if (j == -1 || p[i] == p[j]) //p[i]表示后缀,p[j]表示前缀
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
int KMPSearch(char * t, char * p)
{
int i = 0;
int j = 0;
while (i < strlen(t) && j < strlen(p))
{ //如果j=-1或者当前字符匹配成功,都令i++,j++
if (j == -1 || t[i] == p[j])
{
i++;
j++;
}
else
{ //如果j!=-1,且当前字符匹配失败,则令i不变
//next[j]为即为j所对应的next值
j = next[j];
}
}
if (j == strlen(p))
return i - j;
else
return -1;
}