《数据结构》课件CHAP004 (串)
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DestroyString(&S) StrLength(S) Concat (&T, S1, S2) SubString (&Sub, S, pos, len) Index (S, T, pos) StrInsert (&S, pos, T)
1.StrAssign (&T, chars)
初始条件:chars 是字符串常量。 操作结果:把 chars 赋为 T 的值。
A=“This is a string” B=“is” 则B是A的子串,A为主串。B在A中出现了两次,B在A 中的序号为 ?3 。
特别地,空串是任意串的子串,任意串是其自身的子串。
二、串的抽象数据类型的定义:
ADT String { 数据对象:
D={ ai |ai∈CharacterSet, i=1,2,...,n, n≥0 }
数据关系:
R1={ < ai-1, ai > | ai-1, ai ∈D, i=2,...,n }
基本操作: ……
} ADT String
基本操作:
StrAssign (&T, chars) StrCopy (&T, S) StrCompare (S, T) StrEmpty (S) ClearString (&S) Replace (&S, T, V) StrDelete (&S, pos, len)
i pos=5
i=pos; j=1;
S=„a b a b c a b c a c b a b‟ T=„a b c a c‟
while ( i< = S[0] && j< = T[0] ) {
j
if (S[i] = = T[j] ) {++i; ++j;} //继续比较后续字符
else {i=i-j+2; j=1;} //指针回溯到 下一首位,重新开始匹配
1)基本思想 2)问题关键 3)Next[j]的求解方法 4)Next[j]的求解算法 5)KMP算法
1)基本思想: 每当匹配过程中出现字符串比较不等时,不再需
回溯i 指针,而是利用已经得到的“部分匹配”结果 将模式向右“滑动”尽可能远的一段距离后,继续进 行比较。
2)问题关键: 假设主串为“s1s2,...sn",模式串
11.StrInsert (&S, pos, T)
初始条件:串S和T存在, 1≤pos≤StrLength(S)+1。
操作结果:在串S的第pos个字符之前 插入串T。
例如:S = chater,T = rac, 则执行 StrInsert(S, 4, T)之后得到
S = character
12.StrDelete (&S, pos, len)
while ( i< = S[0] && j< = T[0] ) {
j
if (S[i+k] = = T[j] ) {++k; ++j;} //继续比较后续字符
else {i=i+1; j=1; k=0;} }
//指针回溯到 下一首位,重新开始
从主串下一个字符位置开始匹配
if(j>T[0]) return i;
}
从主串下一个字符位置开始匹配
i=i-j+1+1
if(j>T[0]) return i-T[0]; //子串结束,说明匹配成功
else return 0; }//Index
匹配成功后指针仍要回溯!因为要返回的是被匹 配的首个字符位置。
2.KMP算法
该算法是D.E.Knuth 与V.R.Pratt和J.H.Morris同时 发现的,因此人们称为KMP算法。此算法可以在O(n+m) 的时间数量级上完成串的模式匹配操作。
初始条件:串S和T存在,T是非空串,
1≤pos≤StrLength(S)。 操作结果:
若主串 S 中存在和串 T 值相同 的子串, 则返回它在主串 S 中第 pos个字符之后第一次出现的位 置;否则函数值为0。
“子串在主串中的位置”意指子串 中的第一个字符在主串中的位序。
假设 S = abcaabcaaabc, T = bca Index(S, T, 1) = 2; Index(S, T, 3) = 6; Index(S, T, 8) = 0;
第4章 串
4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 串的模式匹配
4.1 串的抽象数据类型的定义
一、串的基本概念
1.串是零个或多个字符组成的有限序列。记作 S=“a1a2a3…an”,S 是串名,双引号括起来的字符序 列是串值;ai(1≦i≦n)可以是字母、数字或其它字
符。
2.串中所包含的字符个数称为该串的长度。长度为 零的串称为空串,它不包含任何字符。
typedef struct node{ char data; struct node *next;
}lstring;
◆一个链串由头指针唯一确定。这种结构便于进行插 入和删除运算,但存储空间利用率太低。
4.3 串的模式匹配
一、定义
子串的定位运算通常称为串的模式匹配。
设串s=“a1a2…an”,串 T=“b1b2…bm”(m≤n), 子串定位是要在主串S中找出一个与子串T相同 的子串。通常把主串S称为目标,把子串T称为 模式,把从目标S中查找模式为T的子串的过程 称为“模式匹配”。
二、匹配结果
1. 匹配成功:若S中有模式为T的子串,就 返回该子串在S中的位置,当S中有多个模 式为T的子串,通常只要找出第一个子串 即可。
2. 匹配失败:若S中无模式为T的子串,返 回值为零。
动画演示
三、匹配算法*:BF算法和KMP算法
1.BF算法
S=„a b a b c a b c a c b a b‟
10.Replace (&S, T, V)
初始条件:
串S, T和 V 均已存在,且 T 是非空串。
操作结果:
用V替换主串S中出现的所有与T相等的不 重叠的子串。
例如: 假设 S = abcaabcaaabca,T = bca 若 V = x, 则经置换后得到
S = axaxaax
若 V = bc, 则经置换后得到 S = abcabcaabc
5.StrCompare(S,T)
初始条件:串S 和 T 存在。 操作结果:若S T,则返回值 0;
若S T,则返回值 0; 若S T,则返回值 0。
当且仅当两个串的值相 等,即两个串的长度相 等,并且各个对应位置
的字符都相等。
例如:StrCompare(data, state) < 0
3.通常将仅由一个或多个空格组成的串称为空白串。
注意:空串和空白串的不同,例如“ ”和“”分 别表示长度为1的空白串和长度为0的空串。
4.串中任意个连续字符组成的子序列称为该串的子串 ,包含子串的串相应地称为主串。
5.通常将子串在主串中首次出现时的该子串的首字 符对应的主串中的序号,定义为子串在主串中的序 号。 例如,设A和B分别为
联接而成的新串。
例如: Concat( T, man, kind) 求得: T = mankind
8.SubString (&Sub, S, pos, len)
初始条件:
串 S 存在,1≤pos≤StrLength(S) 且0≤len≤StrLength(S)-pos+1。
操作结果:
用 Sub 返回串 S 的第 pos 个字符起 长度为 len 的子串。
子串为“串”中的一个字符子序列 例如: SubString( sub, commander, 4, 3) 求得 sub = man ; SubString( sub, commander, 1, 9) 求得 sub = commander; SubString( sub, commander, 9, 1) 求得 sub = r;
① BF算法设计思想: pos=5 T=„a b c a c‟
• 将主串的第pos个字符和模式的第1个字符比较,
若相等,继续逐个比较后续字符;
若不等,从主串的下一字符(pos+1)起,重新与第一
个字符比较。
• 直到主串的一个连续子串字符序列与模式相等 。返回值 为S中与T匹配的子序列第一个字符的序号,即匹配成功。 否则,匹配失败,返回值 0 .
为”p1p2...pn",当主串中第i个字符与模式串中第j 个字符“失配”(比较不等)时,主串第i字符(i指 针不回溯)应与模式中哪个字符再比较?
StrCompare(cat, case) > 0
6.StrLength (S) 初始条件:串 S 存在。 操作结果:返回 S 的元素个数,
称为串的长度。
例如:StrLength(data)=4 StrLength(dirtreeformat)=13
7.Concat (&T, S1, S2) 初始条件:串 S1 和 S2 存在。 操作结果:用 T 返回由 S1 和 S2
2.StrCopy (&T, S) 初始条件:串 S 存在。 操作结果:由串 S 复制得串 T。
3.DestroyString (&S)
初始条件:串 S 存在。 操作结果:串 S 被销毁。
4.StrEmpty(S)
初始条件:串S存在。 操作结果:若 S 为空串,则返回TRUE,
否则返回 FALSE。
SubString(sub, commander, 4, 7) sub = ?
SubString(sub, beijing, 7, 2) = ? sub = ?
起始位置和子串长度之间存在约束关系
SubString(student, 5, 0) =
长度为 0 的子串为“合法”串
9.Index (S, T, pos)
//子串结束,说明匹配成功
else return 0; }//Index
匹配成功后指针仍要回溯!因为要返回的是被匹 配的首个字符位置。
② BF算法的实现—即Index()操作的实现2
int Index(SString S, SString T, int pos) {
//返回T在S中第pos个字符之后的位置
} HString;
通常: 在C语言中提供的串类型就 是以这种存储方式实现的。系统利用 函数malloc( )和free( )进行串值空间的 动态管理,为每一个新产生的串分配 一个存储区,称串值共享的存储空间 为“堆”。
三、串的链式存储结构
顺序串上的插入和删除操作不方便,需要移 动大量的字符。因此,可用单链表方式来存储 串值,串的这种链式存储结构简称为链串。
3.对串长有两种表示方法:
1)可使用一个不会出现在串中的特殊字符在 串值的尾部来表示串的结束。
如:C语言中以字符‵最大值maxstrlen 为256,但最多只能存放255个字符的原因,因为 必须留一个字节来存放‵\0′字符。
2)可用下标为[0]的数据元素来存储串的长度。
② BF算法的实现—即Index()操作的实现1
int Index(SString S, SString T, int pos) {
//返回T在S中第pos个字符之后的位置
i pos=5 k
i=pos; j=1;k=0;
S=„a b a b c a b c a c b a b‟ T=„a b c a c‟
一、串的定长顺序存储表示
1.定长顺序存储结构:是直接使用定长的字符数 组来定义,数组的上界预先给出:
#define MAXSTRLEN 255 typedef char SString[MAXSTRLEN+1]; SString s; //s是一个可容纳255个字符的顺序串
2.特点:串的实际长度可在予定义长度的范围内随意设 定,超过予定义长度的串值则被舍去,称之为“截断”
如:PASCAL语言中的串类型就采用这种方法。
二、串的堆分配存储表示
以一组地址连续的存储单元存放串值字符 序列,但它们的存储空间是在程序执行过程中 动态分配而得。所以也称为动态存储分配的顺 序表。
typedef struct { char *ch; // 若是非空串,则按串长分配存储区, // 否则ch为NULL int length; // 串长度
初始条件:串S存在 1≤pos≤StrLength(S)-len+1。
操作结果:从串S中删除第pos个字符 起长度为len的子串。
13.ClearString (&S)
初始条件:串S存在。 操作结果:将S清为空串。
4.2 串的表示
一、串的定长顺序存储表示 二、串的堆分配存储表示 三、串的链式存储结构