数据结构复习笔记 3

来源:互联网 发布:p2p无线监控软件 编辑:程序博客网 时间:2024/06/05 08:50

字符串——字符数组——线性表

串及其基本运算

串的基本概念

1.串的定义

串是由零个或多个任意字符组成的字符序列。一般记作:s="s1 s2 … sn"。
其中s 是串名;在本书中,用双引号作为串的定界符,引号引起来的字符序列为串值,引号本身不属于串的内容;ai(1<=i<=n)是一个任意字符,它称为串的元素,是构成串的基本单位,i 是它在整个串中的序号; n 为串的长度,表示串中所包含的字符个数,当n=0 时,称为空串,通常记为Ф。

2.几个术语

子串与主串:串中任意连续的字符组成的子序列称为该串的子串。包含子串的串相应地称为主串。
子串的位置:子串的第一个字符在主串中的序号称为子串的位置。
串相等:称两个串是相等的,是指两个串的长度相等且对应字符都相等。

串的基本运算

串的运算有很多,下面介绍部分基本运算:

1.求串长StrLength(s)
操作条件:串s 存在
操作结果:求出串s 的长度。

2.串赋值StrAssign(s1,s2)
操作条件: s1 是一个串变量,s2 或者是一个串常量,或者是一个串变量(通常s2 是一个串常量时称为串赋值,是一个串变量称为串拷贝)。
操作结果:将s2 的串值赋值给s1, s1 原来的值被覆盖掉。

3.连接操作:StrConcat (s1,s2,s) 或StrConcat (s1,s2)
操作条件:串s1,s2 存在。
操作结果:两个串的联接就是将一个串的串值紧接着放在另一个串的后面,连接成一个串。前者是产生新串s,s1 和s2 不改变; 后者是在s1 的后面联接s2 的串值,s1 改变, s2不改变。
例如: s1="he",s2=" bei",前者操作结果是s="he bei";后者操作结果是s1="he bei"。

4.求子串SubStr (s,i,len):
操作条件:串s 存在,1≤i≤StrLength(s),0≤len≤StrLength(s)-i+1。
操作结果:返回从串s 的第i 个字符开始的长度为len 的子串。len=0 得到的是空串。
例如:SubStr("abcdefghi",3,4)= "cdef"

5.串比较StrCmp(s1,s2)
操作条件:串s1,s2 存在。
操作结果:若s1==s2,操作返回值为0;若s1

串的定长顺序存储及基本运算

因为串是数据元素类型为字符型的线性表,所以线性表的存储方式仍适用于串,也因为字符的特殊性和字符串经常作为一个整体来处理的特点,串在存储时还有一些与一般线性表不同之处。

4.2.1 串的定长顺序存储

类似于顺序表,用一组地址连续的存储单元存储串值中的字符序列,所谓定长是指按预定义的大小,为每一个串变量分配一个固定长度的存储区,如:

#define MAXSIZE 256char s[MAXSIZE];

则串的最大长度不能超过256。

如何标识实际长度?

  1. 类似顺序表,用一个指针来指向最后一个字符,这样表示的串描述如下:
typedef struct{ char data[MAXSIZE];int curlen;} SeqString;

定义一个串变量:SeqString s。这种存储方式可以直接得到串的长度:s.curlen+1。

这里写图片描述

  1. 在串尾存储一个不会在串中出现的特殊字符作为串的终结符,以此表示串的结尾。比如C 语言中处理定长串的方法就是这样的,它是用’\0’来表示串的结束。这种存储方法不能直接得到串的长度,是用判断当前字符是否是’\0’来确定串是否结束,从而求得串的长度。

    这里写图片描述

  2. 设定长串存储空间:char s[MAXSIZE+1]; 用s[0]存放串的实际长度,串值存放在s[1]~s[MAXSIZE],字符的序号和存储位置一致,应用更为方便。

定长顺序串的基本运算

本小节主要讨论定长串联接、求子串、串比较算法,顺序串的插入和删除等运算基本与顺序表相同,在此不在赘述。串定位在下一小节讨论,设串结束用'\0'来标识。

1.串联接:把两个串s1 和s2 首尾连接成一个新串s ,即:s<=s1+s2。

int StrConcat1(s1,s2,s)char s1[],s2[],s[];{ int i=0 , j, len1, len2;len1= StrLength(s1); len2= StrLength(s2)if (len1+ len2>MAXSIZE-1) return 0 ; /* s 长度不够*/j=0;while(s1[j]!=’\0’) { s[i]=s1[j];i++; j++; }j=0;while(s2[j]!=’\0’) { s[i]=s2[j];i++; j++; }s[i]=’\0’; return 1;}

2.求子串

int StrSub (char *t, char *s, int i, int len)/* 用t 返回串s 中第个i 字符开始的长度为len 的子串1≤i≤串长*/{ int slen;slen=StrLength(s);if ( i<1 || i>slen || len<0 || len>slen-i+1){ printf("参数不对"); return 0; }for (j=0; j<len; j++)t[j]=s[i+j-1];t[j]=’\0’;return 1;}

3.串比较

int StrComp(char *s1, char *s2){ int i=0;while (s1[i]==s2[i] && s1[i]!=’\0’) i++;return (s1[i]-s2[i]);}

模式匹配

串的模式匹配即子串定位是一种重要的串运算。设s 和t 是给定的两个串,在主串s中找到等于子串t 的过程称为模式匹配,如果在s 中找到等于t 的子串,则称匹配成功,函数返回t 在s 中的首次出现的存储位置(或序号),否则匹配失败,返回-1。t 也称为模式。为了运算方便,设字符串的长度存放在0 号单元,串值从1 号单元存放,这样字符序号与存储位置一致。

1.简单的模式匹配算法
算法思想如下:首先将s1 与t1 进行比较,若不同,就将s2 与t1 进行比较,…,直到s的某一个字符si 和t1 相同,再将它们之后的字符进行比较,若也相同,则如此继续往下比较,当s 的某一个字符si 与t 的字符tj 不同时,则s 返回到本趟开始字符的下一个字符,即si-j+2,t 返回到t1,继续开始下一趟的比较,重复上述过程。若t 中的字符全部比完,则说明本趟匹配成功,本趟的起始位置是i-j+1 或i-t[0],否则,匹配失败。设主串s="ababcabcacbab",模式t="abcac",匹配过程如图4.3 所示。

这里写图片描述

依据这个思想,算法描述如下:

int StrIndex_BF (char *s,char *t)/*从串s 的第一个字符开始找首次与串t 相等的子串*/{ int i=1,j=1;while (i<=s[0] && j<=t[0] ) /*都没遇到结束符*/if (s[i]==t[j]){ i++;j++; } /*继续*/else{i=i-j+2; j=1; } /*回溯*/if (j>t[0]) return (i-t[0]); /*匹配成功,返回存储位置*/else return1;}
0 0
原创粉丝点击