【Day7·超详细】数据结构 之 串的存储与基础操作(包含朴素模式匹配算法(BF))

导读

本篇文章将会介绍串的顺序存储方式以及基本操作,包括:串赋值操作、串复制操作、串的判空、串求长度、清除串、销毁串、拼接串、找子串、比较串和最重要的串的模式匹配(定位串),对于模式匹配,此篇仅介绍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;//未找到 
}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值