数据结构-第4章 串
合集下载
严蔚敏数据结构-第四章 串

S1 4 a b c d S2 2 e f T 6 a b c d e f
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的子串
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的子串
数据结构——第4章 串(C#)

将当前链串的所有结点?nstr将q结点插入到尾部将q结点插入到尾部将链串t的所有结点?nstr将q结点插入到尾部尾结点的next置为null返回新建的链串5求子串substrij返回当前串中从第i个字符开始的连续j个字符组成的子串ຫໍສະໝຸດ 第4章 串4.1 串的基本概念
4.1.1 什么是串 串(或字符串)是由零个或多个字符组成的有限序列。 记作str="a1a2…an"(n≥0),其中str是串名,用双引号括 起来的字符序列为串值,引号是界限符,ai(1≤i≤n)是一 个任意字符(字母、数字或其他字符),它称为串的元素, 是构成串的基本单位,串中所包含的字符个数n称为串的 长度,当n=0时,称为空串。
4.2 串的存储结构
4.2.1 串的顺序存储结构-顺序串
和顺序表一样,用一个data数组(大小为MaxSize)和 一个整型变量length来表示一个顺序串,length表示data数 组中实际字符的个数。 定义顺序串类SqStringClass如下:
class SqStringClass { const int MaxSize=100; public char[] data; //存放串中字符 public int length; //存放串长 public SqStringClass() //构造函数,用于顺序串的初始化 { data=new char[MaxSize]; length=0; } //顺序串的基本运算 }
(9)串输出DispStr() 将当前串s的所有字符构成一个字符串并输出。对应的算 法如下:
public string DispStr() { int i; string mystr=""; if (length==0) mystr = "空串"; else { for (i=0;i<length;i++) mystr+=data[i].ToString(); } return mystr; }
4.1.1 什么是串 串(或字符串)是由零个或多个字符组成的有限序列。 记作str="a1a2…an"(n≥0),其中str是串名,用双引号括 起来的字符序列为串值,引号是界限符,ai(1≤i≤n)是一 个任意字符(字母、数字或其他字符),它称为串的元素, 是构成串的基本单位,串中所包含的字符个数n称为串的 长度,当n=0时,称为空串。
4.2 串的存储结构
4.2.1 串的顺序存储结构-顺序串
和顺序表一样,用一个data数组(大小为MaxSize)和 一个整型变量length来表示一个顺序串,length表示data数 组中实际字符的个数。 定义顺序串类SqStringClass如下:
class SqStringClass { const int MaxSize=100; public char[] data; //存放串中字符 public int length; //存放串长 public SqStringClass() //构造函数,用于顺序串的初始化 { data=new char[MaxSize]; length=0; } //顺序串的基本运算 }
(9)串输出DispStr() 将当前串s的所有字符构成一个字符串并输出。对应的算 法如下:
public string DispStr() { int i; string mystr=""; if (length==0) mystr = "空串"; else { for (i=0;i<length;i++) mystr+=data[i].ToString(); } return mystr; }
数据结构 第四章 串

第四章 串
4.1 4.2
串类型的定义 串的表示和实现
4.2.1 定长顺序存储表示 4.2.2 堆分配存储表示 4.2.3 串的块链存储表示
第四章 串
4.1 串类型的定义
一、串的基本概念 定义:字符串是 n ( 0 ) 个字符的有限序列
记作 S = “c1c2c3…cn”
其中:
S 是串名字 “c1c2c3…cn”是串值 ci 是串中字符 n 是串的长度
4.1 串类型的定义
一、串的基本概念
串中任意个连续字符组成的子序列称为该串的
子串,包含子串的串相应地称为主串。
子串在主串中首次出现时的该子串的首字符 对应的主串中的序号,定义为子串在主串中的
序号(或位置)
例如,设A和B分别为 A=“This is a string” B=“is”
4.1 串类型的定义
提取子串的算法示例
pos = 3, len = 3 infini ty
pos = 6, len = 4 infini ty
fin
len S[0]-pos+1
超出 len > S[0]-pos+1
合法参数条件: Pos>=0, Pos<=S[0], Len>=0
len <=S[0]-pos+1
求子串的过程即为复制字符序列的过程,将串S中的 第pos个字符开始长度为len的字符复制到串T中。
1、串的插入的动态实现过程 s.length+ t.length
SA
l o v el y
pos Tl o
t.length
vely
g irl!
t.length
1、串的插入的动态实现过程 s.length+ t.length
4.1 4.2
串类型的定义 串的表示和实现
4.2.1 定长顺序存储表示 4.2.2 堆分配存储表示 4.2.3 串的块链存储表示
第四章 串
4.1 串类型的定义
一、串的基本概念 定义:字符串是 n ( 0 ) 个字符的有限序列
记作 S = “c1c2c3…cn”
其中:
S 是串名字 “c1c2c3…cn”是串值 ci 是串中字符 n 是串的长度
4.1 串类型的定义
一、串的基本概念
串中任意个连续字符组成的子序列称为该串的
子串,包含子串的串相应地称为主串。
子串在主串中首次出现时的该子串的首字符 对应的主串中的序号,定义为子串在主串中的
序号(或位置)
例如,设A和B分别为 A=“This is a string” B=“is”
4.1 串类型的定义
提取子串的算法示例
pos = 3, len = 3 infini ty
pos = 6, len = 4 infini ty
fin
len S[0]-pos+1
超出 len > S[0]-pos+1
合法参数条件: Pos>=0, Pos<=S[0], Len>=0
len <=S[0]-pos+1
求子串的过程即为复制字符序列的过程,将串S中的 第pos个字符开始长度为len的字符复制到串T中。
1、串的插入的动态实现过程 s.length+ t.length
SA
l o v el y
pos Tl o
t.length
vely
g irl!
t.length
1、串的插入的动态实现过程 s.length+ t.length
数据结构第4章 串

ring s, SString t)
/*若串s和t相等则返回0;若s>t则返回正数;若s<t则返 回负数*/
{ int i;
for (i=0;i<s.len&&i<t.len;i++)
if (s.ch[i]!=t.ch[i]) return(s.ch[i] - t.ch[i]);
初 始 条 件 : 串 S 存 在 ,1≤pos≤StrLength(S) 且 1≤len≤StrLength(S)-pos+1
操作结果:用Sub返回串S的第pos个字符起长度为len的子串
返回主目录
(11)StrIndex(S,T,pos)
初始条件: 串S和T存在,T是非空串, 1≤pos≤StrLength(S)
return(s.len); }
返回主目录
(7)清空函数
StrClear(SString *s) /*将串s置为空串*/ {
s->len=0; }
返回主目录
(8)连接函数
(1) 连接后串长≤MAXLEN,则直接将B加在A的 后面。 (2) 连接后串长>MAXLEN且LA<MAXLEN,则B 会有部分字符被舍弃。 (3) 连接后串长>MAXLEN且LA=MAXLEN,则B 的全部字符被舍弃(不需连接)。
for (i=s->len + t.len-1;i>=t.len + pos;i--)
s->ch[i]=s->ch[i-t.len];
for (i=0;i<t.len;i++) s->ch[i+pos]=t.ch[i];
s->len=s->len+t.len;
/*若串s和t相等则返回0;若s>t则返回正数;若s<t则返 回负数*/
{ int i;
for (i=0;i<s.len&&i<t.len;i++)
if (s.ch[i]!=t.ch[i]) return(s.ch[i] - t.ch[i]);
初 始 条 件 : 串 S 存 在 ,1≤pos≤StrLength(S) 且 1≤len≤StrLength(S)-pos+1
操作结果:用Sub返回串S的第pos个字符起长度为len的子串
返回主目录
(11)StrIndex(S,T,pos)
初始条件: 串S和T存在,T是非空串, 1≤pos≤StrLength(S)
return(s.len); }
返回主目录
(7)清空函数
StrClear(SString *s) /*将串s置为空串*/ {
s->len=0; }
返回主目录
(8)连接函数
(1) 连接后串长≤MAXLEN,则直接将B加在A的 后面。 (2) 连接后串长>MAXLEN且LA<MAXLEN,则B 会有部分字符被舍弃。 (3) 连接后串长>MAXLEN且LA=MAXLEN,则B 的全部字符被舍弃(不需连接)。
for (i=s->len + t.len-1;i>=t.len + pos;i--)
s->ch[i]=s->ch[i-t.len];
for (i=0;i<t.len;i++) s->ch[i+pos]=t.ch[i];
s->len=s->len+t.len;
数据结构--第四章 串

则:串s3是s1的子串, s1是s3的主串;
串s2不是s1的子串
5
串的概念
串的位置:字符在序列中的序号为 该字符在串中的位置。子串在主 串中的位置则以子串的第一个字 符在主串中的位置来表示。特别 地,空串是任意串的子串,任意 串是其自身的子串。 例如: s1=’I have a dog’; s3=’dog’ 则:子串s3在s1中的位置为匹配(求子串位置) 第一趟:
i=1
a b a b c a b c a c b a b
J=1
a b c
31
串基本操作的实现 —— 串的模式匹配(求子串位置) 第一趟:
i=3
a b a b c a b c a c b a b
J=3
a b c
32
串基本操作的实现 —— 串的模式匹配(求子串位置) 第二趟:
D A T A S T R U C T U R E
D U R
A S C E
T T T
A R U
19
串的存储结构——动态存储结构
串的动态存储方式采用链式存储结构 和堆存储结构两种形式: (一) (二) 块链存储 堆结构
20
串的动态存储结构 ——块链存储的引入
用单链表存放串,每个结点仅存储一个字符, 每个结点的指针域所占空间比字符域所占空间 要大得多。定义如下: typedef struct node{ char ch; struct node *next;
9
串的基本操作定义
⑵ 判等函数:Equal(s,t)
若s和t相等, 则返回函数值(即运算结 果)1, 否则返回函数值 0。s和t可以是 非空串,也可以是空串。 例如, 执行Equal (a,b) 后, 值为0。 执行Equal (‘abc’,‘abc’) 后, 值为1。
数据结构第四章(串)

return ERROR;
Sub[1…len]=S[pos…pos+len-1]; Sub[0]=len; return OK; }//SubString
小结:串的顺序存储结构特点: 实现串操作的原操作为“字符序列的复制 ”,操作的时间复 杂度基于复制的字符序列的长度;
如果在操作中出现串值序列的长度超过上界MAXSTRLEN时, 约定用截尾法处理。
1. 类似顺序表,定义一个表示串长度的域;
typedef struct { char ch[MAXSTRLEN];
int len;
}SqString;
2.串长可用下标为0的数组元素存储; 3.也可在串值后设特殊标记,‘\0‟:
a[0]
3 a
a[1]
a b
a[2]
b c
a[3]
c \0
a[4]
a[5]
}
else { // S1[0] = MAXSTRSIZE截断(仅取S1) T[0..MAXSTRLEN] = S1[0..MAXSTRLEN]; uncut = FALSE; }
return uncut;
} // Concat
2.求子串SubString(&Sub,S,pos,len)
Status SubString(Sstring &sub,Sstring S, int pos , int len){ //其中,1=<pos<=StrLength(s)且 0=<len<=StrLength(s)-pos+1。 //用sub返回S串中从第pos个位置开始,长度为len的字符串 if (pos<1|| pos>s[0] || len<0 || < len>S[0]-pos+1)
《数据结构》--第四章 串

4.3 串的基本运算
4、插入子串: insert(s,s1,i) 在串s的第i个位置插入串s1。 5、删除子串: delete(s,i,j) 从串s的第i个位置开始,连续删除j个 字符。 6、子串定位: match(s,s1) 返回子串s1在串s中第一次出现的位置。 7、子串替换: replace(s,s1,i,j) 将串s中从第i个位置开始的长度 为j的子串用串s1来替换。
1. 串连接
串连接就是把两个串连接在一起,其中一个 串接在另一个串的末尾,生成一个新串。 如给出两个串s1和s2,把s2连接到s1之后, 生成一个新串s。
1. 串连接
例如,有两个串分别为s1 = ″Good ″, s2 = ″morning!″,则调用函数connect(s1, s2) 后,生成一个新串s = ″Good morning!″
4.2 串的存储结构
4.2.1 串的静态存储结构
串的静态存储结构采用顺序存储结构,简称为顺 序串。在计算机中,一个字符只占一个字节,所以串 中的字符是顺序存放在相邻字节中的。 串的顺序存储可用一个字符型数组和一个整型变 量来表示,其中字符型数组存放串值,整型变量存放 串的长度。
4.2 串的存储结构
4.2.2 串的链式存储结构
串的链式存储结构也称为链串,结构与链表类似,链串 中每个结点有两个域,一个是值域(data),用于存放字符 串中的字符,另一个是指针域(next),用于存放后继结点 的地址。 一个链串一般是由头指针唯一确定的。
优点:插入、删除运算很方便。
4.2 串的存储结构
存储密度 = 串值所占的存储位 / 实际分配的存储位 为了提高存储密度,可让每个结点的值域存放多个字符。 这种结构也叫做大结点结构。 如串s = “good morning!”的存储结构如下图所示。
最新课件-数据结构教学第4章串 精品

例如, 设链表中每个结点只存放一个字符, 则在C语言中可 使用如下说明:
struct list struct list * next; /* 指向下一个结点的指针 */ char data; /* 字符 */
} * point; /* point为结构类型的指针, 指向第一结点 */ 根据上述说明, 字符串′string′的链表存储可用图4.1表示。 如果链表中每个结点可存放4个字符, 则结点结构为: struct list struct list * next;
4.2.2 串的链表存储
由于各种串运算与串的存储方式有密切关系 , 若要随机存 取串中第K个字符, 顺序存储显得比较方便; 若要对串进行插入、 删除等操作, 顺序存储就显得比较繁琐, 而链表存储则显示出 明显的优越性。
链表存储是把可利用的存储空间分成一系列大小相同的 结点 ( 若干连续的存储单元 ), 每个结点含有两个域 : data 域和 next域。 data域用来存放字符; next域用来存放指向下一个结点 (首地址)的指针。 结点的大小是指data域中可以存放字符的个 数, next域的大小则取决于寻址的范围。
元中仅放一个字符。 在一个程序中使用的串变量较少, 且各串 变量的长度又都较短时,如果希望该程序处理字符的速度尽 可能快, 那么选择非紧缩格式比较合适。 在这种存储格式中, 串的长度是隐式的, 串所占用存储单元的个数即为串长。
例: 假设一存储单元可以存放4个字符, 同样对于字串(This is a flag), 共需14个存储单元, 其存放的直观表示如表 4.2。 这 种存储格式对存储空间的利用率仅为25%, 但如上所述, 该方法 在字符加工处理方面会节省时间。 3) 某些计算机( 如一般的微型计算机 ), 是以字节为存取单位 的, 一个字符通常又占用一个字节, 这就自然形成了每个存储 单位存放一个字符的分配方式。这种方式一般不需要存放串 长的存储单元, 而需要以程序中各变量值所不包含的字符作为 结束符。 例: 在C语言中, 字符串存放在一个连续的存储单元中, 一 个字符占一个字节。对于字符串′STRING′, 在微机中只需 7 个 存储单元。直观表示如下:
struct list struct list * next; /* 指向下一个结点的指针 */ char data; /* 字符 */
} * point; /* point为结构类型的指针, 指向第一结点 */ 根据上述说明, 字符串′string′的链表存储可用图4.1表示。 如果链表中每个结点可存放4个字符, 则结点结构为: struct list struct list * next;
4.2.2 串的链表存储
由于各种串运算与串的存储方式有密切关系 , 若要随机存 取串中第K个字符, 顺序存储显得比较方便; 若要对串进行插入、 删除等操作, 顺序存储就显得比较繁琐, 而链表存储则显示出 明显的优越性。
链表存储是把可利用的存储空间分成一系列大小相同的 结点 ( 若干连续的存储单元 ), 每个结点含有两个域 : data 域和 next域。 data域用来存放字符; next域用来存放指向下一个结点 (首地址)的指针。 结点的大小是指data域中可以存放字符的个 数, next域的大小则取决于寻址的范围。
元中仅放一个字符。 在一个程序中使用的串变量较少, 且各串 变量的长度又都较短时,如果希望该程序处理字符的速度尽 可能快, 那么选择非紧缩格式比较合适。 在这种存储格式中, 串的长度是隐式的, 串所占用存储单元的个数即为串长。
例: 假设一存储单元可以存放4个字符, 同样对于字串(This is a flag), 共需14个存储单元, 其存放的直观表示如表 4.2。 这 种存储格式对存储空间的利用率仅为25%, 但如上所述, 该方法 在字符加工处理方面会节省时间。 3) 某些计算机( 如一般的微型计算机 ), 是以字节为存取单位 的, 一个字符通常又占用一个字节, 这就自然形成了每个存储 单位存放一个字符的分配方式。这种方式一般不需要存放串 长的存储单元, 而需要以程序中各变量值所不包含的字符作为 结束符。 例: 在C语言中, 字符串存放在一个连续的存储单元中, 一 个字符占一个字节。对于字符串′STRING′, 在微机中只需 7 个 存储单元。直观表示如下:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
真子串是指不包含自身的所有子串。
4.1 串的类型定义
子串的序号:将子串在主串中首次出现时的该 子串的首字符对应在主串中的序号,称为子串 在主串中的序号(或位置)。 【例】 A=“abcdefbbcd”,B=“bcd”,B在A中的 序号为2。 特别地,空串是任意串的子串,任意串是其自 身的子串。
4.1.2 串的抽象数据类型定义
//查找ab子串
if (p->data==‘ a’ && p->next->data==‘b’)
{ p->data=‘x’; p->next->data=‘z’;
q=(LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data=‘y’;
q->next=p->next; p->next=q;
s: a a a a b c d
t: a ab bac acb bc c ✓ 匹配成功 算法的思路是从s的每一个字符开始依次与t的 字符进行匹配。
4.2.1 Brute-Force算法
int BFIndex(SqString s,SqString t)
{ int i=0, j=0,k;
while (i<s.length && j<t.length)
4.1 串的类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法
本章要求
理解: 1、串的基本概念、类型定义 2、串的存储表示和实现 3、串的KMP算法
掌握: 4、串的简单模式匹配算法(BF)
第4章 串的基本概念
串(或字符串):是由零个或多个字符组成 的有限序列。
串的逻辑表示: S=“a1a2…ai…an”,其中S为 串名,ai (1≤i≤n)代表单个字符,可以是字母、 数字或其它字符(包括空白符)。 串值:双引号括起来的字符序列。双引号不是 串的内容,只起标识作用。
串抽象数据类型=逻辑结构+基本运算 ADT String{
数据对象: D ={ ai|ai∈ElemSet, i=1,2,…,n,n≥0 } 数据关系: R ={<ai-1, ai>|ai-1,ai∈D, i=2,4,…,n }
4.1.2 串的抽象数据类型定义
基本操作:
StrAssign(&s,cstr):将字符串常量cstr赋给串s,即生成其值等 于cstr的串s。 StrCopy(&s,t):串复制。将串t赋给串s。 StrEqual(s,t):判串相等。若两个串s与t相等则返回真;否则返 回假。 StrLength(s):求串长。返回串s中字符个数。 DelStr(s,i,j):删除。从串s中删去从第i(1≤i≤n)个字符开 始的长度为j的子串,并返回产生的新串。 StrInsert(s1,i,s2):插入。在串s1第i个位置插入字符串s2,并返回 新串。
4.1.2 串的抽象数据类型定义
RepStr(s,i,j,t):替换。在串s中,将第i(1≤i≤n)个字符开 始的j个字符构成的子串用串t替换,并返回产生的新串。 DispStr(s):串输出。输出串s的所有元素值。 Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串 。 SubStr(s,i,j,sub):求子串。返回串s中从第i(1≤i≤n)个字 符开始的、由连续j个字符组成的子串,由sub返回。
} ADT Stack
4.1.3 串的存储表示和实现
串的存储方式取决于将要对串所进行的操作。 在计算机中有3种表示方式:
静态顺序存储表示:将串定义成字符数组, 利用串名可以直接访问串值。用这种表示方式, 串的存储空间在编译时确定,其大小不能改变。
4.1.3 串的存储表示和实现
动态顺序存储方式:仍然用一组地址连续的存 储单元来依次存储串中的字符序列,但串的存 储空间是在程序运行时根据串的实际长度动态 分配的。
} StringType ;
4.1.4 串的静态顺序存储表示
(1) 串的联结操作
StringType StrConcat ( StringType s, StringType t){ /* 将串t联结到串s之后,结果仍然保存在s中 */ int i; if ((s.length+t.length)>MaxSize) return 0; /* 联结后长度超出范围 */ /*strcat(s.str,t.str);*/ for (i=0 ; i<t.length ; i++) s.str[s.length+i]=t.str[i] ; /* 串t联结到串s之后 */ s.length=s.length+t.length ; /* 修改联结后的串长度 */ return s;}
T->length=s1->length+s2->length +1; 为最后的\0预留位置
if ((T->ch=(char *)malloc(sizeof((char)* T->length))==NULL)) { printf(“系统空间不够,申请空间失败 !\n”) ;
return 0 ; }
为模式匹配或串匹配(字符串匹配) 。
目标串s 是子串吗?
模式串t
模式匹配
成功是指在目标串s中找到一个模式串t,t是s
的子串,返回t在s中的位置。
不成功则指目标串s中不存在模式串t,t不是s
的子串,返回-1。
4.2.1 Brute-Force算法
Brute-Force简称为BF算法,亦称简单匹配算法。 采用穷举的思路。
查找:p->data=‘a’ && p->next->data=‘b’ p
…
a
b
…
4.1.6 串的链式存储表示
替换
s
p
…
xa
bz
…
qy
s
…x
y
zLeabharlann …4.1.6 串的链式存储表示
void Repl(LinkStrNode *s){ LinkStrNode *p=s->next,*q;
int find=0; while (p->next!=NULL && find==0){
if (s.data[i]==t.data[j])
//继续匹配下一个字符
{ i++;
j++;} //主串和子串依次匹配下一个字符
else //主串、子串指针回溯重新开始下一次匹配
{ i=k+1; //主串从下一个位置开始匹配
j=0; flag=0;
} //子串从头开始匹配
}
if (j>=t.length) return(k); //返回匹配的第一个字符的下标
若每个结点仅存放一个字符,则结点的指针域 就非常多,造成系统空间浪费。
为节省存储空间,考虑串结构的特殊性,使每 个结点存放若干个字符,这种结构称为块链结构。
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
LiSi
Boy
…
结点大小为4的链串
#define MaxSize 4
typedef struct StrNode
{ char data[MaxSize] ;
struct StrNode *next;
}LinkStrNode ;
18 ∧
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
s
A
B
…
Z∧
结点大小为1的链串
typedef struct StrNode
{
char data ;
struct StrNode *next;
free(s1->ch) ; free(s2->ch) ; return 1; }
4.1.6 串的链式存储表示
串的链式存储结构和线性表的串的链式存储结 构类似,采用单链表来存储串:
data域:存放字符,data域可存放的字符个数称 为结点的大小; next域:存放指向下一结点的指针。
4.1.6 串的链式存储表示
find=1;
} else p=p->next;
}}
作业
设计如下算法:char* StrRelace(char T[], char P[], char S[]),将T中第一次出现的与P相等的 子串替换为S(串S和P的长度不一定相等),并 分析时间复杂度。
4.2 串的模式匹配
模式匹配(模范匹配):子串在主串中的定位称
串的长度(或串长):串中所含字符的个数, 含零个字符的串称为空串。
第4章 串的基本概念
串相等: 当且仅当两个串的长度相等并且各个对应位 置上的字符都相同时,这两个串才是相等的。 【例】:“abcd” ≠ “abc”
“abcd” ≠ “abce” 注:所有空串是相等的。
第4章 串的基本概念
子串:一个串中任意个连续字符组成的子序 列(含空串)称为该串的子串。 【例】 “abcde”的子串有: “”、“a”、“ab” 、“abc”、“abcd” 和“abcde”等
}LinkStrNode ;
4.1.6 串的链式存储表示
【单选题】用带头结点的单链表来表示串s,则串s 为空串的条件是( ) A.s->next==NULL B.s==NULL C.s->next==s D.s->next->next==NULL
4.1.6 串的链式存储表示
【例】在链串中,设计一个算法把最先出现的 子串“ab”改为“xyz”。
}
4.1.4 串的静态顺序存储表示
练习1
设计顺序串上实现串比较运算Strcmp(s,t)的算法
4.1 串的类型定义
子串的序号:将子串在主串中首次出现时的该 子串的首字符对应在主串中的序号,称为子串 在主串中的序号(或位置)。 【例】 A=“abcdefbbcd”,B=“bcd”,B在A中的 序号为2。 特别地,空串是任意串的子串,任意串是其自 身的子串。
4.1.2 串的抽象数据类型定义
//查找ab子串
if (p->data==‘ a’ && p->next->data==‘b’)
{ p->data=‘x’; p->next->data=‘z’;
q=(LinkStrNode *)malloc(sizeof(LinkStrNode));
q->data=‘y’;
q->next=p->next; p->next=q;
s: a a a a b c d
t: a ab bac acb bc c ✓ 匹配成功 算法的思路是从s的每一个字符开始依次与t的 字符进行匹配。
4.2.1 Brute-Force算法
int BFIndex(SqString s,SqString t)
{ int i=0, j=0,k;
while (i<s.length && j<t.length)
4.1 串的类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法
本章要求
理解: 1、串的基本概念、类型定义 2、串的存储表示和实现 3、串的KMP算法
掌握: 4、串的简单模式匹配算法(BF)
第4章 串的基本概念
串(或字符串):是由零个或多个字符组成 的有限序列。
串的逻辑表示: S=“a1a2…ai…an”,其中S为 串名,ai (1≤i≤n)代表单个字符,可以是字母、 数字或其它字符(包括空白符)。 串值:双引号括起来的字符序列。双引号不是 串的内容,只起标识作用。
串抽象数据类型=逻辑结构+基本运算 ADT String{
数据对象: D ={ ai|ai∈ElemSet, i=1,2,…,n,n≥0 } 数据关系: R ={<ai-1, ai>|ai-1,ai∈D, i=2,4,…,n }
4.1.2 串的抽象数据类型定义
基本操作:
StrAssign(&s,cstr):将字符串常量cstr赋给串s,即生成其值等 于cstr的串s。 StrCopy(&s,t):串复制。将串t赋给串s。 StrEqual(s,t):判串相等。若两个串s与t相等则返回真;否则返 回假。 StrLength(s):求串长。返回串s中字符个数。 DelStr(s,i,j):删除。从串s中删去从第i(1≤i≤n)个字符开 始的长度为j的子串,并返回产生的新串。 StrInsert(s1,i,s2):插入。在串s1第i个位置插入字符串s2,并返回 新串。
4.1.2 串的抽象数据类型定义
RepStr(s,i,j,t):替换。在串s中,将第i(1≤i≤n)个字符开 始的j个字符构成的子串用串t替换,并返回产生的新串。 DispStr(s):串输出。输出串s的所有元素值。 Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串 。 SubStr(s,i,j,sub):求子串。返回串s中从第i(1≤i≤n)个字 符开始的、由连续j个字符组成的子串,由sub返回。
} ADT Stack
4.1.3 串的存储表示和实现
串的存储方式取决于将要对串所进行的操作。 在计算机中有3种表示方式:
静态顺序存储表示:将串定义成字符数组, 利用串名可以直接访问串值。用这种表示方式, 串的存储空间在编译时确定,其大小不能改变。
4.1.3 串的存储表示和实现
动态顺序存储方式:仍然用一组地址连续的存 储单元来依次存储串中的字符序列,但串的存 储空间是在程序运行时根据串的实际长度动态 分配的。
} StringType ;
4.1.4 串的静态顺序存储表示
(1) 串的联结操作
StringType StrConcat ( StringType s, StringType t){ /* 将串t联结到串s之后,结果仍然保存在s中 */ int i; if ((s.length+t.length)>MaxSize) return 0; /* 联结后长度超出范围 */ /*strcat(s.str,t.str);*/ for (i=0 ; i<t.length ; i++) s.str[s.length+i]=t.str[i] ; /* 串t联结到串s之后 */ s.length=s.length+t.length ; /* 修改联结后的串长度 */ return s;}
T->length=s1->length+s2->length +1; 为最后的\0预留位置
if ((T->ch=(char *)malloc(sizeof((char)* T->length))==NULL)) { printf(“系统空间不够,申请空间失败 !\n”) ;
return 0 ; }
为模式匹配或串匹配(字符串匹配) 。
目标串s 是子串吗?
模式串t
模式匹配
成功是指在目标串s中找到一个模式串t,t是s
的子串,返回t在s中的位置。
不成功则指目标串s中不存在模式串t,t不是s
的子串,返回-1。
4.2.1 Brute-Force算法
Brute-Force简称为BF算法,亦称简单匹配算法。 采用穷举的思路。
查找:p->data=‘a’ && p->next->data=‘b’ p
…
a
b
…
4.1.6 串的链式存储表示
替换
s
p
…
xa
bz
…
qy
s
…x
y
zLeabharlann …4.1.6 串的链式存储表示
void Repl(LinkStrNode *s){ LinkStrNode *p=s->next,*q;
int find=0; while (p->next!=NULL && find==0){
if (s.data[i]==t.data[j])
//继续匹配下一个字符
{ i++;
j++;} //主串和子串依次匹配下一个字符
else //主串、子串指针回溯重新开始下一次匹配
{ i=k+1; //主串从下一个位置开始匹配
j=0; flag=0;
} //子串从头开始匹配
}
if (j>=t.length) return(k); //返回匹配的第一个字符的下标
若每个结点仅存放一个字符,则结点的指针域 就非常多,造成系统空间浪费。
为节省存储空间,考虑串结构的特殊性,使每 个结点存放若干个字符,这种结构称为块链结构。
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
LiSi
Boy
…
结点大小为4的链串
#define MaxSize 4
typedef struct StrNode
{ char data[MaxSize] ;
struct StrNode *next;
}LinkStrNode ;
18 ∧
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
s
A
B
…
Z∧
结点大小为1的链串
typedef struct StrNode
{
char data ;
struct StrNode *next;
free(s1->ch) ; free(s2->ch) ; return 1; }
4.1.6 串的链式存储表示
串的链式存储结构和线性表的串的链式存储结 构类似,采用单链表来存储串:
data域:存放字符,data域可存放的字符个数称 为结点的大小; next域:存放指向下一结点的指针。
4.1.6 串的链式存储表示
find=1;
} else p=p->next;
}}
作业
设计如下算法:char* StrRelace(char T[], char P[], char S[]),将T中第一次出现的与P相等的 子串替换为S(串S和P的长度不一定相等),并 分析时间复杂度。
4.2 串的模式匹配
模式匹配(模范匹配):子串在主串中的定位称
串的长度(或串长):串中所含字符的个数, 含零个字符的串称为空串。
第4章 串的基本概念
串相等: 当且仅当两个串的长度相等并且各个对应位 置上的字符都相同时,这两个串才是相等的。 【例】:“abcd” ≠ “abc”
“abcd” ≠ “abce” 注:所有空串是相等的。
第4章 串的基本概念
子串:一个串中任意个连续字符组成的子序 列(含空串)称为该串的子串。 【例】 “abcde”的子串有: “”、“a”、“ab” 、“abc”、“abcd” 和“abcde”等
}LinkStrNode ;
4.1.6 串的链式存储表示
【单选题】用带头结点的单链表来表示串s,则串s 为空串的条件是( ) A.s->next==NULL B.s==NULL C.s->next==s D.s->next->next==NULL
4.1.6 串的链式存储表示
【例】在链串中,设计一个算法把最先出现的 子串“ab”改为“xyz”。
}
4.1.4 串的静态顺序存储表示
练习1
设计顺序串上实现串比较运算Strcmp(s,t)的算法