导读
本篇文章将会介绍串的顺序存储方式以及基本操作,包括:串赋值操作、串复制操作、串的判空、串求长度、清除串、销毁串、拼接串、找子串、比较串和最重要的串的模式匹配(定位串),对于模式匹配,此篇仅介绍BF算法,KMP算法将在下一节进行详细说明。
串
基本概念
- 串:0个或多个字符组成的有限序列。
- 串的长度:串中字符的个数
- 空串:长度为0的串
- 空格串:0个或多个空格字符组成的串
- 子串:串中任意连续字符组成的子序列
- 主串:包含子串的串
- 位置:字符在串中的序号。ps:子串在主串中的位置是其第一个字符在主串中的位置。
- 串的相等:长度和对应位置字符都相等
与线性表的差别:串的数据对象限制为字符,并且一般以串作为整体进行操作。
对于串的顺序存储,我们可以想到多个方案,第一个就是用字符数组从下标0开始存储串,在字符数组最后一个位置存放串的长度,第二个是下标0位置不存储串,在下标0位置放串的长度,这样可以保证下标与字符位置的统一,但局限性是由于是char类型,所以能表示的长度仅有2的8次方(即0--255)(char是一个字节)(实际是-127--+127第一个比特位表示的符号,1负0正!)
在此,我们采用的方法是,用一个整型变量去保存length并空出下标为0的字符:
下面将一一介绍串的一些操作:
1.初始化 赋值 复制 判空 求长 清除 销毁
StringPtr InitString(void)
{
StringPtr S=(StringPtr)malloc(sizeof(String));
S->length=0;
return S;
}
Status StrAssign(StringPtr T,char *s)
{
int len=strlen(s);
T->length=len;
int i;
for(i=1;i<=len;i++) T->data[i]=s[i];
return OK;
}
Status StrCopy(StringPtr T,StringPtr S)//串复制
{
T->length=S->length;
int i;
for(i=1;i<=T->length;i++) T->data[i]=S->data[i];
return OK;
}
Status StrEmpty(StringPtr S)//串判空
{
if(S->length==0) return TRUE;
else return FALSE;
}
int StringLength(StringPtr S)
{
//串长
return S->length;
}
Status ClearString(StringPtr S)
{
S->length=0;
return OK;
}
Status DestroyString(StringPtr S)
{
//销毁串
free(S->data);
free(S);
return OK;
}
2.连接 求子串 比较
Status StrConcat(StringPtr S1,StringPtr S2,StringPtr T)
{
//串连接
if(S1->length+S2->length>199) return ERROR;
int i;
for(i=1;i<=S1->length;i++) T->data[i]=S1->data[i];
for(;i<=S1->length+S2->length;i++) T->data[i]=S2->data[i];
T->length=S1->length+S2->length;
return OK;
}
Status SubString(StringPtr sub,StringPtr S,int pos,int len)
{
//求子串
if(len>199) return ERROR;
sub->length=len;
int i;
for(i=pos;i<=pos+len;i++)
sub->data[i]=S->data[i];
return OK;
}
int StrCompare(StringPtr S1,StringPtr S2)
{
//串比较
if(S1->length!=S2->length) return S1->length>S2->length?1:0;
else
{
int i;
for(i=1;i<=S1->length;i++)
{
if(S1->data[i]!=S2->data[i]) return S1->data[i]>S2->data[i]?1:0;
}
return 0;
}
}
3.模式匹配(核心)
时间复杂度:
最好情况:
匹配成功:O(m) 匹配失败: O(n)
最坏情况:
成功/失败 :O(m*n)
int Index_BF(StringPtr S,StringPtr T)
{
int k=1;
int i=k;
int j=1;
while(i<=S->length&&j<=T->length)
{
if(S->data[i]==T->data[i])
{
i++;
j++;
}
else
{
k++;
i=k;
j=1;
}
}
if(j>T->length) return k;
else return 0;//未找到
}