第4章 串
严蔚敏数据结构-第四章 串

15
(2)S1串长 最大串长 串长<最大串长 串长 最大串长; S1,S2串长和 最大串长 串长和>最大串长 串长和 最大串长;
S1 6 a b c d e f S2 6 g h i j k l T 8 a b c d e f g h
3
串的抽象数据类型的定义: 串的抽象数据类型的定义: ADT String{ 数据对象: 数据对象:D={ai|ai∈CharacterSet, i=1,2,...,n, n>=0} 数据关系: 数据关系:R1={<ai-1,ai>|ai-1,ai∈D, i=2,...,n} 基本操作: 基本操作: StrAssign(&T, chars)
11
作业: 作业: 1.用5种串的基本操作(StrAssign、StrCompare、StrLen Concat、SubString)来逻辑实现StrInsert(&S, pos, T)操作 、 操作. )
Status StrInsert(String S, int pos , String T) { if ……….. return error; , , ); ); ); );
chars是字符串常量。生成一个其值等于chars的串 。 是字符串常量。生成一个其值等于 的串T。 是字符串常量 的串
StrCopy(&T, S)
存在则由串S复制得串 串S存在则由串 复制得串 存在则由串 复制得串T
StrEmpty(S)
存在则若S为空串 串S存在则若 为空串 返回真否则返回假 存在则若 为空串,返回真否则返回假
Sub返回串 的第pos个字符起长度为 返回串S的第 个字符起长度为len的子串 用Sub返回串S的第pos个字符起长度为len的子串
第四章串A

(1)初始化ClearString(S):初始化串S(串S存 在,将S清为空串)。 (2)StrAssign(&T,char):生成串。
(3)StrCopy(&T,S):串复制(将串S复制到串T)。5
第4 章 串
(4)Concat(&T,s1,s2):串联接(用T返回S1,S2 联接而成的新串)。 (5)求串长StrLength(S):返回S串的元素个数, 即S串的长度。 (6)串比较StrCompare(S,T) (7)求子串SubString(&Sub,S,pos,len): 返回s串的第pos个字符起始的长度为len的子串。 (8)插入运算SetInsert(&S,T,pos):把串t的 值插入到串s的第pos个字符之后。 (9)删除运算StrDelte(&S,pos,len):将串s
可能出现如下三种情况: a. S1长度+S2长度<=T长度,则S1+S2可以完整放入T中; b. S1长度+S2长度>T长度,则S1完整放入,S2放入一部 分; c. S1长度=T长度,则S1完整放入,S2不能放入。 注意:各串长度数据放入该串的 0 单中。(如图4.1示)
11
第4 章 串
两串联结的C语言程序 (算法4.2)
{ int i; orderstribg *r ;
printf(“ r1=%s,r2=%s\n”,r1.vec,r2.vec);
if (r1.len+r2.len>m0) printf(“上溢出\n”) ; /* 若两串长度之和大于m0,则进行溢出处理*/
12
第4 章 串
else { for (i=0; i<r1.len; i++) r.vec[i]=r1.vec[i]; for (i=0; i<r2.len;i++) /*将串r2传r */ r.vec[r1.len+ i ]= r2.vec[i]; r.vec[r1.len+ i ]=“\0” ; /*最后一个位置赋给\0 */ r.len=r1.len+r2.len; } return(r); } /*r串长度等于两串长度之和*/ /*将串r1传给r */
第4章 字符串v

空串: 空串: 长度为0的字符串 的字符串; 长度为 的字符串; 空格串: 空格串: 由空格字符组成的字符串,长度>1 由空格字符组成的字符串,长度 主串: 主串: 包含该子串的字符串; 包含该子串的字符串; 字符的位置: 字符的位置: 从1开始 开始 子串的位置: 子串的位置: 该子串第一个字符的位置
定长顺序存储标识串的实际长度时可有三种方式: 定长顺序存储标识串的实际长度时可有三种方式:
(1)用一个指针指向最后一个字符,串描述类似顺序表 用一个指针指向最后一个字符, 用一个指针指向最后一个字符 #define MAXSIZE 256 typedef struct { char data[MAXSIZE]; int curlen; }SeqString; 定义一个串变量:SeqString s; 定义一个串变量
1.串的 定长 顺序存储 串的(定长 串的 定长)顺序存储
(定长 顺序存储结构类似于C语言的字符数组,以一 定长)顺序存储结构类似于 语言的字符数组, 定长 顺序存储结构类似于 语言的字符数组 组地址连续的存储单元存放串值中的字符序列, 组地址连续的存储单元存放串值中的字符序列,定长即是预 先为每一个串变量分配一个固定长度的存储区,例如: 先为每一个串变量分配一个固定长度的存储区,例如: #define MAXSIZE 256 char s[MAXSIZE] 那么,串的最大长度就不能超过 那么,串的最大长度就不能超过256。 。
第4章 串 章
4.1 字符串的基本概念
4. 2 串的存储结构
4.3 模式匹配
(1) 串的基本概念
串(string)是由零个或多个任意字符组成的字符序列, )是由零个或多个任意字符组成的字符序列, 又称为字符串( 又称为字符串(character string),一般记为: ) 一般记为: s=〝a1 a2 a3 … an〞
第四章:串

第四章串一、选择题1.下面关于串的的叙述中,哪一个是不正确的?()A.串是字符的有限序列 B.空串是由空格构成的串C.模式匹配是串的一种重要运算 D.串既可以采用顺序存储,也可以采用链式存储2 若串S1=‘ABCDEFG’, S2=‘9898’ ,S3=‘###’,S4=‘012345’,执行concat(replace(S1,substr(S1,length(S2),length(S3)),S3),substr(S4,index(S2,‘8’),length(S2)))其结果为()【北方交通大学 1999 一、5 (25/7分)】A.ABC###G0123 B.ABCD###2345 C.ABC###G2345 D.ABC###2345E.ABC###G1234 F.ABCD###1234 G.ABC###012343.设有两个串p和q,其中q是p的子串,求q在p中首次出现的位置的算法称为()A.求子串 B.联接 C.匹配 D.求串长4.已知串S=‘aaab’,其Next数组值为()。
A.0123 B.1123 C.1231 D.12115.串‘ababaaababaa’的next数组为()。
【中山大学 1999 一、7】A.012345678999 B.012121111212 C.011234223456 D.0123012322345 6.字符串‘ababaabab’的nextval 为()A.(0,1,0,1,04,1,0,1) B.(0,1,0,1,0,2,1,0,1)C.(0,1,0,1,0,0,0,1,1) D.(0,1,0,1,0,1,0,1,1 )7.模式串t=‘abcaabbcabcaabdab’,该模式串的next数组的值为(),nextval数组的值为()。
A.0 1 1 1 2 2 1 1 1 2 3 4 5 6 7 1 2 B.0 1 1 1 2 1 2 1 1 2 3 4 5 6 1 1 2 C.0 1 1 1 0 0 1 3 1 0 1 1 0 0 7 0 1 D.0 1 1 1 2 2 3 1 1 2 3 4 5 6 7 1 2 E.0 1 1 0 0 1 1 1 0 1 1 0 0 1 7 0 1 F.0 1 1 0 2 1 3 1 0 1 1 0 2 1 7 0 18.若串S=’software’,其子串的数目是()。
第四章 串图文

在上述串的抽象数据类型定义的13种操作中,串 赋值StrAssign、串复制Strcopy、串比较 StrCompare、求串长StrLength、串联接Concat以 及求子串SubString等六种操作构成串类型的最小 操作子集。即:这些操作不可能利用其它串操作 来实现,而其它串操作(除串清除ClearString和 串销毁DestroyString外)如定位函数Index( S, T, pos )可在这个最小操作子集上实现如p72。
例如:C语言函数库中提供下列串处理函数:
gets(str) 输入一个串; puts(str) 输出一个串; strcat(str1, str2) 串联接函数; strcpy(str1, str2, k) 串复制函数; strcmp(str1, str2) 串比较函数; strlen(str) 求串长函数;
子串的定位
Replace (&S, T, V) 串的置换 StrInsert (&S, pos, T) 串的插入
StrDelete (&S, pos, len) 串的删除
} ADT String
StrAssign (&T, chars)
(串的赋值)
初始条件:chars 是字符串常量。
操作结果:把 chars中的字符串 常量 赋给 T。
StrDelete (&S, pos, len)
初始条件:串S存在
1≤pos≤StrLength(S)-len+1。
操作结果:从串S中删除第pos个字符 起长度为len的子串。
ClearString (&S)
初始条件:串S存在。 操作结果:将S清为空串。
串的基本操作集可以有不同的定义方法, 在使用高级程序设计语言中的串类型时,以该 种语言的参考手册为准。
第4章 串

4.2.1 定长顺序存储表示 串的连接算法
第4章 串
Status Concat(SString S1, SString S2, SString &T) { // 用T返回由S1和S2联接而成的新串。若未截断, 则返回TRUE,否则FALSE。 ………………. else if (S1[0] <MAXSTRSIZE) { // 截断 T[1..S1[0]] = S1[1..S1[0]]; T[S1[0]+1…MAXSTRLEN] = S2[1…MAXSTRLEN-S1[0]]; T[0] = MAXSTRLEN; uncut = FALSE; }
第4章 串
字符串本身就是一个线性表,可以用链表存储。 如果每个结点存储一个字符,如采用32位地
址,字符按8位记,则存储密度是多少?
存储密度 = 数据元素所占存储位 实际分配的存储位 8 =20% 40
21
存储密度 =
4.2.3 串的块链存储表示 链表存储字符串的讨论
第4章 串
结论:采用普通链表存储字符串,存储密度非常 低,浪费空间严重。 解决办法:一个结点存储多个字符。这就是串的 块链存储。
5
4.1 串类型的定义 串与一般线性表的区别
第4章 串
(1) 串数据对象约束为字符集。
(2) 基本操作的对象不同,线性表以“单个元素”
为操作对象;串以“串的整体”为操作对象,操作的 一般都是子串。
6
4.1 串类型的定义 串的ADT定义 ADT String {
第4章 串
数据对象:D={ ai |ai∈CharacterSet,i=1,2,...,n, n≥0 } 数据关系: R1={ < ai-1, ai > | ai-1, ai ∈D, i=2,...,n } 基本操作: } ADT String
串

ClearString (&S)
初始条件:串S存在。 操作结果:将S清为空串。
Concat (&T , S1, S2)
初始条件:串S1和S2存在。 操作结果:用T返回由S1和S2联接而成的新串。
Status ClearString(HString &S) { //将S清为空串. if(S.ch) { free(S.ch); S.ch=NULL;} S.length=0; return OK; }// ClearString
Status Concat(HString &T, HString S1, HString S2)
int Strlength(HString S) { return S.length; }
int StrCompare(HString S, HString T) { //若S>T,则返回值>0;若S = T,则返回值=0;若S<T,则返回值<0 for( i=0; i< S.length && i< T.length; ++i ) if(S.ch[i]!= T.ch[i]) return S.ch[i]-T.ch[i]; return S.length- T.length; }
• 二、串的抽象数据类型的定义
ADT String { 数据对象:D={ai| ai∈CharacterSet; i=1,2,…,n,;n≥0} 数据关系:R1={<ai-1, ai>| ai-1, ai∈D; i= 2,…,n} 基本操作: StrAssign (&T , chars)
第四章 串

– 例如
• 主串S = • 子串T = CD • 则index(S,T),返回子串T在S中,第一次出现的位置3
19
串的模式匹配
Brute-Force算法基本思想: • 从目标串s 的第一个字符起和模式串t的第一个字符进行比较 • 若相等,则继续逐个比较后续字符,否则从串s 的第二个字 符起再重新和串t进行比较。 • 依此类推,直至串t 中的每个字符依次和串s的一个连续的字 符序列相等,则称模式匹配成功,此时串t的第一个字符在串s 中的位置就是t 在s中的位置,否则模式匹配不成功。
两式联立可得:“T0…Tk-1”= “Tj-k…Tj-1”
注意:j为当前已知的失配位置,我们的目标是计算新起点k。式中仅剩 一个未知数k,理论上已可解!
奇妙的结果:k仅与模式串T有关!
27
新起点k怎么求?
根据模式串T的规律:“T0…Tk-1”=“Tj-k …Tj-1” 由当前失配位置j(已知),归纳计算新起点k的表达式。
j=next[j]的位置(即模式串继续向右移动),再比较 si 和 tj 。
依次类推,直到下列两种情况之一: 1)j退回到某个j=next[j]时有 si = tj,则指针各增1,继续匹配; 2)j退回至j=0,此时令指针各增1,即下一次比较 si+1和 t0 。
30
串的模式匹配:KMP算法
• 模式串的next函数
6
串的基本概念
4.两个字符串相等的充分必要条件为两个字符串的长度相等,并 且对应位置上的字符相等。
例如:‘abcd’ ≠ ‘bacd’ ‘abcd’ = ‘abcd’
7
串的基本操作
1.给串变量赋值 ASSIGN(S1,S2)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章 串
串长的两种表示方法:
1. 放在下标为0的数组分量中(PASCAL)
2. 设置一个字符串结束标志(C语言)
定长顺序存储可能带来的问题(P73)
第四章 串 4.2.2 堆分配存储表示 这种存储表示的特点是,仍以一组地址连续 的存储单元存放串值字符序列,但它们的存 储空间是在程序执行过程中动态分配而得。 所以也称为动态存储分配的顺序表。在C语言 中,利用动态存储管理函数,来根据实际需 要动态分配和释放字符数组空间。
第四章 串
第4章 串
数据结构(C描述)
第四章 串
目录
4.1 串类型的定义 4.2 串的表示和实现
第四章 串
4.1 串类型的定义
4.1.1 基本概念 1.串的定义 串( string) 是由零个或多个字符组成的有限序列, 记作s=„a1a2…an‟,其中s为串的名字,用成对的 单引号括起来的字符序列为串的值,但两边的 单引号不算串值,不包含在串中。ai(1≤i≤n)可以 是字母、数字或其它字符。n为串中字符的个数, 称为串的长度。
第四章 串
上述所定义的基本操作中有5中操 作最基本的,串的其余操作可由这 些基本操作组合而成
第四章 串 例1、串的定位index(S,T,pos) 基本思想:在主串中取从第i个字符起、长度 和串T相等的子串和T比较,若相等,则求得函 数值为i,否则值增1直至S中不存在和串T相等 的子串为止。
第四章 串
第四章 串 (1) 求串长(length) int strlen(char s); //求串的长度 例如:printf(“%d”,strlen(s1)); 输出13 (2) 串复制(copy) char *strcpy(char to,char from); 该函数将串from复制到串to中,并且返回 一个 指向串to的开始处的指针。 例如:strcpy(s3,s1); //s3=“dirtreeformat”
第四章 串 10、Replace(&S , T , V) 初始条件:串S,T,V存在,T是非空串 操作结果:用V替换主串中船舷的所有与T相等的 不重叠的子串。 11、StrInsert(&S , pos , T) 初始条件:串S和串T存在,1posStrLength(S) 操作结果:在串S的第pos个字符前插入串 T
第四章 串 if(!(s.ch=(char*)realloc(s.ch,(s.length+t.length)*s izeof(char))) exit(overflow); for(i=s.length-1;i>=pos-1;--i) s.ch[i+t.length]=s.ch[i]; s.ch[pos-1..pos+t.length-2]=t.ch[0..t.length-1]; s.length+=t.length; } return OK; }
第四章 串
4.1.2 串的抽象数据类型描述
串的抽象数据类型可描述为: ADT String { 数据对象:D={ai | ai ∈CharacterSet, i=1,2,...,n n≥0 } 数据关系:R1={ < ai-1, ai >| i=2,...,n } 基本操作: , ai-1, ai ∈D,
第四章 串
(3) 联接(concatenation) char strcat(char to,char from) 该函数将串from复制到串to的末尾,并且返回一 指向串to的开始处的指针。 例如:strcat(s3,”/”) strcat(s3,s2); //s3=“dirtreeformat/file.mem”
第四章 串 √8、SubString(&Sub, S , pos , len) 初始条件:串S存在,1posStrLength(S) 且0 len StrLength(S)-pos+1 操作结果:用Sub返回串S的第pos个字符起 长度 为len的子串。 9、Index(S , T , pos) 初始条件:串S和T存在,T是非空串, 1posStrLength(S) 操作结果:若主串S中存在和串T值相同的 子串, 则返回它在主串S中
第四章 串
4.2 串的表示与实现
因为串是特殊的线性表,故其存储结构与线 性表的存储结构类似。只不过由于组成串的结 点是单个字符。串有三种机内表示方法,下面 分别介绍。 4.2.1定长顺序存储表示 定长顺序存储表示,也称为静态存储分配的 顺序表。它是用一组连续的存储单元来存放串 中的字符序列。所谓定长顺序存储结构,是直 接使用定长的字符数组来定义,数组的上界预 先给出:
第四章 串 (4)串比较(compare) int strcmp(chars1,char s2); 该函数比较串s1和串s2的大小,当返回值小于0, 等于0或大于0时分别表示s1<s2\s1=s2或s1>s2 例如:result=strcmp(“baker”,”Baker”) result>0 result=strcmp(“12”,”12”); result=0 result=strcmp(“Jos”,”Joseph”); result<0
第四章 串 12、StrDelete(&S, pos , len) 初始条件:串S存在,1posStrLength(S)-len+1 操作结果:从串S中删除第pos个字符起长度为len 的子串。
13、DestroyString(&S) 初始条件:串S存在 操作结果:串S被销毁
}ADT String
第四章 串
4.1.3 串的基本操作
对于串的基本操作,许多高级语言均提供了相应的 运算或标准库函数来实现。下面仅介绍几种在C语 言中常用的串运算。
定义下列几个变量: char s1[20]=“dirtreeformat”,s2[20]=“file.mem”; char s3[30],*p; int result;
第四章 串
1. 类型的定义 typedef struct { char *ch; int length; }HString;
第四章 串 2. 基本运算
(1)串插入
Status StrInsert(Hstring& S,int pos,HString t){ // 1posStrLength(S)+1。在串S的第pos个 字符之前插入串T if(pos<1 || pos>s.length+1) return error; if(t.length){
int index(string s,string t,int pos){ if(pos>0){ n=strlen(s); m=strlen(t); i=pos; while(i<n-m+1){ substr(sub,s,i,m); if(strcmp(sub,t)!=0) ++i; else return(i); } } return(0); }
第四章 串
Status StrAssign(HString &T, char *chars){ //生成一个其值等于串常量chars的串T if(T.ch) free(T.ch); for(i=0 , c=chars; c ; ++i, ++c); if (!i) { T.ch=null; T.length=0;} else{ if(!(T.ch=(char *)malloc(i*sizeof(char)))) exit(overflow); T.ch[0..i-1]=chars[0..i-1]; T.length=i; } return OK; }
第四章 串 特别的,空串是任意串的子串,任意串是自身 的子串。 通常在程序中使用的串可分为两种:串变量 和串常量。串常量和整常数、实常数一样,在 程序中只能被引用但不能不能改变其值,即只 能读不能写。通常串常量是由直接量来表示的, 例如语句Error(“overflow”) 中“overflow”是直 接量。但有的语言允许对串常量命名,以使程 序易读、易写。串变量和其它类型的变量一样, 其取值是可以改变的。
√1、StringAssign(&T,chars) 操作结果:生成一个其值等于chars的串T。
第四章 串 2、StrCopy (&T,S) 初始条件:串S已存在。 操作结果:由串S复制得串T。
3、StrEmpty (S) 初始条件:串S已存在。 操作结果:若S为空串,则返回TURE,否则返 回FALSE √ 4、StrCompare(S,T) 初始条件:串S和串T已存在。 操作结果:若S>T,则返回值>0;若S=T,则返 回值=0;若 S<T, 则返回值<0。
(4) 赋 值
第四章 串 (5)串比较 int StrCmpare(HString S,HString T){ //若S>T,则返回值>0;若S=T,则返回值=0; 若S<T,则返回值<0 for(i=0;i<S.length && i<T.length;++i) if(T.ch[i]!=S.ch[i] return(S.ch[i]-T.ch[i]); return S.length-T.length; }
第四章 串
(2)求串长度 int StrLength(HString S) //返回S的元素的个数, 称为串的长度 {
return S.length;
}
第四章 串
(3)清空串 Status ClearString(HString &S){ if(S.ch){free(S.ch); S.ch=NULL;} S.length=0; return OK; }
第四章 串 (6)串联接 Status Concat(HString T,HString S1,HString S2){ //用T返回由S1和S2联接而成的新串 if(!(T.ch)=(char*)malloc(S1.length+S2.length)*si zeof(char))) exit(overflow); T.ch[0..S1.length-1]=S1.ch[0..S1.length-1]; T.length=S1.length+S2.length; T.ch[S1.length..T.length-1]=S2.ch[0..S2.length-1]; return OK; }