数据结构与算法:实验报告(串及其应用)


前言

计算机上非数值处理的对象大部分是字符串数据,字符串一般简称为。串是一种特殊的线性表,其特殊性体现在数据元素是一个字符,也就是说,串是一种内容受限的线性表。


提示:以下是本篇文章正文内容,下面案例可供参考

一、实验目的

掌握串类型的实现方法和文本模式匹配方法。

二、实验内容

使用c语言编写顺序串的所有功能,包括串赋值、串比较、串连接、求串长、求子串、串删除、串置换、子串查找定位等。采用菜单调用的方式实现。

主菜单:

         1:串赋值
         2:求串长
         3:串比较
         4:串连接
         5:求子串
         6:子串插入
         7:子串置换
         8:子串定位
         9:退出

三、实验环境

1)使用的操作系统及版本

Windows10

2)使用的编译系统及版本

Dev-C++ 5.11

四、实验步骤及说明

1、用c语言,设计出串的存储结构

串是一种特殊的线性表,它的数据元素由一个字符组成。在计算机数据处理中,非数值处理的对象经常是字符串数据。串的存储有多种方法,包括定长顺序存储、堆存储及链式存储等,从存储利用上来说,堆存储最有效率,因此本实验以堆存储为基础来设计数据结构。
堆分配存储结构的特点是:仍以一组地址连续的存储单元存放串的字符序列,但其存储空间是在算法执行过程中动态分配得到的。在C语言中,存在一个称之为“堆”的自由存储区,并由C语言的动态分配函数malloc( )和free( )来管理。利用函数malloc( )为每一个新产生的串分配一块实际需要的存储空间,若分配成功,则返回一个指针,指向串的起始地址。

串的堆分配存储结构如下:

typedef struct
{
	char *ch;
	int length;
}HString;

2、对应堆存储,设计出各功能算法。

1)串赋值

int StrAssign(HString *T,char *chars)
{//将字符串chars赋值给串T
	int i,j;
	char *c;
	if(T->ch) free(T->ch); //释放原有的空间
	for(i=0, c=chars; *c; ++i, ++c);  //求chars的长度
	if(!i) {
		T->ch=NULL;
		T->length=0;
	}
	else {  
		if(!(T->ch=(char *)malloc((i+1)*sizeof(char))))
   			return ERROR;
   		for(int n=0; n<(i+1); n++)
			*(T->ch+n)=0;//清空串T
		for (j=0;j<i;j++)
			T->ch[j]=chars[j];
		T->length=i;
	}
	return OK;
}

2)求串长

int StrLength(HString S)
{//返回串S的长度 
	return S.length;
}

3)串比较

Status StrCompare(HString S, HString T)
{//比较串S、T,若S>T返回正数,S=T返回0,S<T返回负数 
	char *SStr = S.ch, *TStr = T.ch;
	while(*SStr==*TStr && *SStr && *TStr)
	{
		SStr++;
		TStr++;
	 } 
	if(*SStr == *TStr)	return 0;
	else 
		return (int)(*SStr-*TStr);
}

4)串连接

Status Concat(HString *T, HString S)
{//将S连接于T,用T返回 
	char *TStr;
	if(!(TStr=(char *)malloc((T->length+S.length+1)*sizeof(char))))
		return ERROR;
	for(int i=0; i<(T->length+S.length+1); i++)
		*(TStr+i)=0;//清空串TStr
	int i=0;
	while(*(T->ch+i)) 
	{//将指针指向pos位置 
		*(TStr+i) = *(T->ch+i);
		i++;
	 }
	while(*(S.ch))
	{
		*(TStr+i) = *(S.ch++);
		T->length++;
		i++;
	}
	free(T->ch);
	T->ch = TStr;
	return OK;
 }

5)求子串

Status SubString(HString *SubS, HString S, int pos, int len)
{//用SubS返回串S的pos位置开始len长的子串 
	char *ch;
	int i=0, x=len;
	if(!(ch=(char*)malloc((len+1)*sizeof(char))))	return ERROR;
	for(int i=0; i<(len+1); i++)
		*(ch+i)=0;//清空串ch 
	if(S.length < (pos+len-1))	return ERROR;
	for(; pos>1; pos--)
		S.ch++;
	for(; x>0; x--)
	{
		*(ch+i) = *S.ch++;
		i++;
	}
		
	SubS->length = len;
	free(SubS->ch);
	SubS->ch = ch;
	return OK;
 }

6)子串插入

Status StrInsert(HString *S, HString SubS, int pos)
{//在串S的pos位置插入子串SunS 
	HString H, X;//创建串H ,X
	H.ch = X.ch = NULL;
	H.length = X.length = 0; //初始化
	if(!(H.ch=(char*)malloc((S->length+SubS.length+1)*sizeof(char))))	
		return ERROR;
	if(!(X.ch=(char*)malloc((S->length+SubS.length)*sizeof(char))))	
		return ERROR;
	SubString(&X, *S, 1, pos-1);//取出S中pos位置前的串存放在X 
	for(int i=0; i<(S->length+SubS.length+1); i++)
		*(H.ch+i)=0;//清空串H 
	Concat(&H, X);//将X中字符串连接在空串H之后  
	Concat(&H, SubS);//将子串连接串H之后 
	SubString(&X, *S, pos, S->length-pos+1);//取出S中pos位置后的串存放在X
	Concat(&H, X);//将pos之后的串连接在串H之后 
	free(S->ch);
	S->ch = H.ch;
	free(X.ch);
	X.ch = NULL;
	return OK;
 }

7)子串置换

Status Replace(HString *S, HString T, HString V)
/* 以串 v 置换串 s 中出现的所有和串 t 相同的非空串  */
{   
    int s,t,v,i;
    HString sub,H;
	sub.length=H.length=0;  
    s = StrLength(*S);
    t = StrLength(T);
    v = StrLength(V);
    i = 1;
    while(i <= s-t+1){
    	sub.ch=H.ch=NULL;
        SubString(&sub, *S, i, t);//将串S中的子串逐个提取出来与串T进行匹配
        if(StrCompare(sub, T) == 0)
		{//匹配相等时
			SubString(&H, *S, 1, i-1);//取出S中i位置前的串存放在H
            Concat(&H, V);//将替换串V连接到串H后
            SubString(&sub, *S, i+t, s-(t+i)+1);//取出匹配相等的子串的后面的子串
            Concat(&H, sub);//将sub连接到串H后
            free((*S).ch);
			(*S).ch = H.ch;
			free(sub.ch);
            i += t;
            s = StrLength(*S);//操作完一次之后,串S已经改变,需要注意
        }
        else{
            ++i;
        }
    }    
}

8)子串定位(BF算法)

int Index_BF(HString *S, HString SubS)
{//使用BF算法,返回子串SubS在主串中的位置 
	int i=0, j=0;
	while(S->ch[i] && SubS.ch[j])
	{
		if(S->ch[i]==SubS.ch[j])
		{
			i++;
			j++;
		}
		else
		{
			i=i-j+1;
			j=0;
		}
	}
	if(!SubS.ch[j])	return i-j+1;
	else return 0;
}

五、实验总结

这次实验的重点在子串插入和子串置换,其中子串置换使用的模式匹配算法更是难点,开始自己依然没理解KMP算法原理,经过不断学习试错,也算大体明白其原理,但是使用时依然有较大问题,最后依然使用了BF算法来完成此次实验。


总结

提示:这里对文章进行总结:
本文是自己数据结构作业的一个记录,因为是假期整理的可能会有错误,欢迎告知。
代码全文以及实验报告原文下载链接
提取码:zryy。

  • 46
    点赞
  • 208
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值