第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑

Slides:



Advertisements
Similar presentations
数据结构——树和二叉树 1/96.
Advertisements

数据结构与算法 (C++语言版) 第4章 串.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
第九章 字符串.
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第四章 串 2018/11/13.
第4章 串 串的基本概念和C语言的串函数 串的存储结构 动态数组实现的顺序串 串的模式匹配算法——BF算法 主要知识点.
数据结构 Data Structure 主讲人:王国军,郑瑾 中南大学 中南大学信息院计科系
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
C语言高级编程(第四部分) 字符串 北京大学 信息科学技术学院.
数据结构 第4章 串.
数据结构——串 1/15.
第四章 串和数组(一) 1/.
走进编程 程序的顺序结构(二).
辅导课程六.
串和数组.
第4章 串 4.1 串的基本概念及其抽象数据 4.2 串的存储结构 4.3 串类 4.4 串的模式匹配算法.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第 3 讲 线性表(一).
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第三章 栈和队列.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 串的模式匹配算法.
第4章 串 4.1 串的基本概念 4.2 串的存储结构 4.3 串的模式匹配.
动态规划(Dynamic Programming)
数据结构概论 第4章 串 董黎刚 浙江工商大学信电学院 2019年1月18日.
第四章串 4.1 串类型定义 4.2 串的表示和实现 4.3 串的模式匹配算法 4.4 串操作应用举例.
第四章 串.
严蔚敏、吴伟民编著 清华大学出版社 学习网站:
第4章 串和数组 本章主要介绍下列内容: 串的定义、存储结构和基本运算 数组的定义、基本运算和存储结构 特殊矩阵的压缩存储.
顺序表的插入.
王玲 第 2 章 线性表 王玲 2019/2/25.
从zval看PHP变量
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
第四章 串.
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
学习目标 1、什么是字符集 2、字符集四个级别 3、如何选择字符集.
顺序表的删除.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 字符串应用 5.4 字符串匹配算法 5.5 数组
5.1 串的基本概念 5.2 串的存储结构 5.3 串的基本运算 5.4 模式匹配 5.5 串在文本编辑中的应用
数 据 结 构 刘家芬 Sept 2012.
第四章 串和数组 4.1 串的定义* 4.2 串的表示和实现* 4.3 数组 4.4 数组的压缩.
单链表的基本概念.
第 四 讲 线性表(二).
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
第4章 Excel电子表格制作软件 4.4 函数(一).
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第九节 赋值运算符和赋值表达式.
3.1.2 空间向量的数量积运算 1.了解空间向量夹角的概念及表示方法. 2.掌握空间向量数量积的计算方法及应用.
3.16 枚举算法及其程序实现 ——数组的作用.
第 六 讲 栈和队列(一).
1.设A和B是集合,证明:A=B当且仅当A∩B=A∪B
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
2.6 字符型数据 一、 字符常量 1、字符常量的定义 用一对单引号括起来的单个字符,称为字符常量。 例如,‘A’、‘1’、‘+’等。
第15讲 特征值与特征向量的性质 主要内容:特征值与特征向量的性质.
第五章 串和数组 5.1 串的定义和操作 5.2 串的表示和实现 5.3 正文匹配模式 5.4 正文编辑 5.5 数组 5.6 数组的压缩.
实验目的:掌握数据的顺序存储结构及它们在计算机中的操作。 实验内容:
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
第四章 串 String
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
本节内容 导出表 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第5章 其他线性数据结构.
Presentation transcript:

第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑 第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑 £4.2.1 定长顺序存储表示 £4.2.2 堆分配存储表示

£4.1 串的定义 串(string)(或字符串):是由零个或多个字符组成的有限 序列,一般记为 (n≥0) 串的长度:串中字符的数目。 空串(null string):零个字符的串,其长度为零。记为“ ”。 Ф 空格串(blank string):由一个或多个空格组成的串。其长度为串中空格 字符的个数。 子串:串中任意个连续的字符组成的子序列。 主串:包含子串的串相应地称为主串。 字符在串中的位置:即字符在序列中的序号。 串相等:当且仅当这两个串的值相等。即,两个串的长度相等,并且 各个对应位置的字符都相等。

例如:假设a、b、c、d为如下的4个串: a = ‘BEI’ , b = ‘JING’ c = ‘BEIJING’ , d = ‘BEI JING’ 它们的长度分别为3、4、7、8;并且a和b都是c和d的子串, a在c和d中的位置都是1,而b在c中的位置是4,在d中的位置则是5。 a、b、c和d彼此都不相等。 串的抽象数据类型定义: 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) 初始条件:chars是字符串常量。 操作结果:生成一个其值等于chars的串T。 StrCopy (&T, S) 初始条件:串S存在。 操作结果:由串S复制得串T。 StrEmpty(S) 操作结果:若S为空串,则返回TRUE,否则返回FALSE。

StrCompare(S, T) 初始条件:串S和T存在。 操作结果:若S>T,则返回值>0;若S=T,则返回值=0; 若S<T,则返回值<0。 StrLength(S) 初始条件:串S存在。 操作结果:返回S的元素个数,称为串的长度。 ClearString (&S) 操作结果:将S清为空串。 Concat (&T, S1, S2) 初始条件:串S1和S2存在。 操作结果:用T返回由S1和S2联接而成的新串。 SubString(&Sub, S, pos, len) 初始条件:串S存在,1≤pos≤StrLength(S)且 0≤len≤StrLength(S)-pos+1 操作结果:用Sub返回串S的第pos个字符长度为len的子串。 Index(S, T, pos) 初始条件:串S和T存在,T是非空串,1≤pos≤StrLength(S)。 操作结果:若主串S中存在和串T值相同的子串,则返回它在主串S 中第pos个字符之后第一次出现的位置;否则函数值为0。 Replace (&S, T, V) 初始条件:串S, T和V存在,T是非空串。 操作结果:用V替换主串S中出现的所有与T相等的不重叠的子串。

初始条件:串S和T存在, 1≤pos≤StrLength(S)+1。 操作结果:在串S的第pos个字符之前插入串T。 StrInsert (&S, pos, T) 初始条件:串S和T存在, 1≤pos≤StrLength(S)+1。 操作结果:在串S的第pos个字符之前插入串T。 StrDelete (&S, pos, len) 初始条件:串S存在, 1≤pos≤StrLength(S)-len+1。 操作结果:从串S中删除第pos个字符起长度为len的子串。 DestroyString (&S) 初始条件:串S存在。 操作结果:串S被销毁。 }ADT String 最小操作子集:串赋值StrAssign、串比较StrCompare、求串长StrLength、 串联接Concat和求子串SubString。 在上述抽象数据类型定义的13种操作中,这5种操作不可能利用其他串操作来实现,但其他串操作均可在这个最小操作子集上实现。

例如:利用判等、求串长和求子串等操作实现定位函 数Index(S, T, pos)。 算法4.1如下: int Index (String S, String T, int pos) { //T为非空串。若主串S中第pos个字符之后存在与T相等的子 //串,则返回第一个这样的子串在S中的位置,否则返回0。 if (pos > 0) { n = StrLength (S); m = StrLength (T); i = pos; while (i <= n-m+1) { SubString (sub, S, i, m); if (StrCompare (sub, T) != 0) ++i; else return i; //返回子串在主串中的位置 } // while } //if return 0; //S中不存在与T相等的子串 } // Index

£4.1 串的定义 £4.2.1 定长顺序存储表示 (1)定义 定长顺序存储结构:用一组地址连续的存储单元存储串值的字符序列。 截断:超过预定义长度的串值被舍去。 (2)C语言描述 在串的定长顺序存储结构中,按照预定义的大小,为每个定义的串变量 分配一个固定长度的存储区,则可用定长数组如下描述之: #define MAXSTRLEN 255 //用户可在255以内定义最大串长 typedef unsigned char SString[MAXSTRLEN+1]; //0号单元存放串的长度 (3)串长的表示方法 ①以下标为0的数组分量存放串的实际长度。如,PASCAL语言中的串 类型采用这种表示方法。 ②在串值后面加一个不计入串长的结束标记字符。此时的串长为隐含 值。如,C语言中以“\0”表示串值的终结。

(4)串联接和求子串操作 ①串联接Concat (&T, S1, S2) 假设S1、S2和T都是SString型的串变量,且串T是由串S1 链结串S2得到的。基于串S1和S2长度的不同情况,串T值的产生 可能有如下3种情况: A. S1[0]+S2[0]≤MAXSTRLEN,得到的串T是正确的结果。如图4.1(a)所示 S1[0] S2[0] S1 S2 T T[0] MAXSTRLEN (a) S1[0]+S2[0]≤MAXSTRLEN

B.S1[0]<MAXSTRLEN,而S1[0]+S2[0]>MAXSTRLEN, 则将串S2的一部分截断,得到的串T只包含串S2的一个子串。 如图4.1(b)所示。 S1[0] S2[0] S1 S2 T T[0] MAXSTRLEN S2中被截去的字符序列 (b) S1[0]<MAXSTRLEN而S1[0]+S2[0]>MAXSTRLEN

C. S1[0]=MAXSTRLEN,则得到的串T并非联接结果, 而和串S1相等。 图4.1 串的联结操作Concat(T,S1,S2)示意图

串联接 算法4.2如下: Status Concat (SString &T, SString S1, SString S2) { //用T返回由S1和S2联接而成的新串。若未截断, //则返回TRUE,否则FALSE. if (S1[0] + S2[0] <= MAXSTRLEN) { //未截断 T[1..S1[0]] = S1[1..S1[0]]; T[S1[0] + 1..S1[0] + S2[0]] = S2[1..S2[0]]; T[0] = S1[0] + S2[0]; uncut = TRUE; } else if (S1[0] < MAXSTRLEN) { //截断 T[S1[0] + 1..MAXSTRLEN] = S2[1..MAXSTRLEN – S1[0]]; T[0] = MAXSTRLEN; uncut = FALSE; else { //截断(仅取S1) T[0..MAXSTRLEN] = S1[0.. MAXSTRLEN]; //T[0] = = S1[0] = = MAXSTRLEN return uncut; } // Concat

②求子串SubString(&Sub, S, pos, len) 个字符开始长度为len的字符序列复制到串Sub中。 算法4.3如下: Status SubString (SString &Sub, SString S, int pos, int len) //用Sub返回串S的第pos个字符起长度为len的子串。 //其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1。 if (pos < 1| | pos > S[0] | | len < 0 | | len > S[0]- pos + 1) return ERROE; Sub[1..len] = S[pos..pos + len - 1]; Sub[0] = len; return OK; } // SubString

£4.2.2 堆分配存储表示 (1)定义 堆分配存储结构:用一组地址连续的存储单元存储串值 的字符序列,但它们的存储空间是在程序执行过程中动态分 配而得。 (2)C语言描述 typedef struct { char *ch; //若是非空串,则按串长分配存储区, //否则ch为NULL int length; //串长度 } HString

(3)插入操作 算法思想:为串S重新分配大小等于串S和串T长度之和 的存储空间,然后进行串值复制。 Status StrInsert (HString &S, int pos, HString T) { //1≤pos≤StrLength(S) + 1。在串S的第pos个字符之前插入串T。 if (pos < 1 | | pos > S.length + 1) return ERROR; //pos不合法 if (T.length) { //T非空,则重新分配空间,插入T if (!(S.ch = (char *)realloc(S.ch, (S.length + T.length)*sizeof(char)))) exit (OVERFLOW); for (i = S.length-1; i >= pos-1;――i) //为插入T而腾出位置 S.ch[i + T.length] = S.ch[i]; S.ch[pos-1..pos + T.length-2] = T.ch[0..T.length-1]; //插入T S.length += T.length; } return OK; } // StrInsert

(4)ADT String的表示和实现 以下所示为只含最小操作子集的HString串类型的模块说明。 //------------------------串的堆分配存储表示-------------------- typedef struct { char *ch; //若是非空串,则按串长分配存储区, //否则ch为NULL int length; //串长度 } HString; //------------------------基本操作的函数原型说明---------------------- Status StrAssign (HString &T, char *chars); //生成一个其值等于串常量chars的串T int StrLength(HString S); //返回S的元素个数,称为串的长度。 int StrCompare(HString S, HString T) //若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0。 Status ClearString (HString &S); //将S清为空串,并释放S所占空间。 Status Concat (HString &T, HString S1, HString S2); //用T返回由S1和S2联接而成的新串。 HString SubString(HString S, int pos, int len); //1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1 //返回串S的第pos个字符起长度为len的子串。

//-------------------基本操作的算法描述-------------------- Status StrAssign (HString &T, char *chars) { //生成一个其值等于串常量chars的串T if (T.ch) free (T.ch); //释放T原有空间 for (i = 0, c = chars; c; ++i, ++c); //求chars的长度i 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; } // StrAssign

int StrLength(HString S) { return S.length; } // StrLength 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; } // StrCompare

Status ClearString (HString &S) { //将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) { //用T返回由S1和S2联接而成的新串。 if (T.ch) free (S.ch); //释放旧空间 if (!(T.ch = (char *) malloc ((S1.length + S2.length) * sizeof (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; } // Concat

HString SubString(HString S, int pos, int len) { //用Sub返回串S的第pos个字符起长度为len的子串。 //其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1 if (pos < 1| | pos > S.length| | len < 0| | len > S.length-pos + 1) return ERROR; if (Sub.ch) free (Sub.ch); //释放旧空间 if (!len) { //空子串 Sub.ch = NULL; Sub.length = 0; } else { Sub.ch = (char *) malloc (len * sizeof (char)); Sub.ch[0..len-1] = S.ch[pos-1..pos + len -2]; Sub.length = len; return OK; } // SubString

£4.3 串的链式存储结构 (串的块链存储表示) (1)定义 块链结构:采用链表方式存储串值,每个结点可以存放一 个字符,也可以存放多个字符。 (2)图形表示 head A B C I ^ (a) 结点大小为1的链表 head A B C D E F G H I # # # ^ (b) 结点大小为4的链表 图4.2 串值的链表存储方式

(3)C语言描述 #define CHUNKSIZE 80 //可由用户定义的块大小 typedef struct Chunk { char ch [CHUNKSIZE]; struct Chunk * next; } Chunk; typedef struct { Chunk * head, * tail; //串的头和尾指针 int curlen; //串的当前长度 } LString; (4)存储密度 显然,存储密度小(如结点大小为1),运算处理方便,然而, 存储占用量大。如果在串处理过程中需进行内、外存交换的话,则 会因为内外存交换操作过多而影响处理的总效率。

£4.4 串的应用—文本编辑 文本编辑的实质是修改字符数据的形式或格式。 文本串:把整个文本看成是一个字符串。页则是文本串的子 串,行又是页的子串。 例如:以下程序便可看成是一个文本串。 main ( ){ float a,b,max; scanf(“%f,%f”,&a,&b); if a>b max=a; else max=b; }; 输入到内存后如图4.3所示。 m a i n ( ) { f l o t , b x ; s c “ % ” & > = e } 图4.3 文本格式示例

为了管理文本串的页和行,在进入文本编辑的时候,编辑 程序先为文本串建立相应的页表和行表,即建立各子串的存储 映像。页表的每一项给出了页号和该页的起始行号。而行表的 每一项则指示每一行的行号、起始地址和该行子串的长度。 假设图4.3所示文本串只占一页,且起始行号为100,则该 文本串的行表如图4.4所示。 行号 起始地址 长度 100 201 8 101 209 17 102 226 24 103 250 17 104 267 15 105 282 2 图4.4 图4.3所示文本串的行表

几种文本编辑的操作: ①插入(文本行):把新插入的行存到文本的末尾。并按行号次序 把新行的行号,起始位置及该行字符串的长度信息插入到行表的合适位置。 ②删除(文本行):把被删除行的行号,起始位置及该行字符串的长 度信息从行表中删去即可(若存储空间较紧张时,应同时从内存中删去 该行)。若被删除的行是所在页的起始行,则还要修改页表中相应页的起 始行号(修改为下一行的行号)。 ③修改(文本行): 1.若新行长≤原行长,则把新行字符串仍存于原行字符串的位 置,并修改行表中该行子串的长度信息即可。 2.若新行长≥原行长,则把新行字符串存于文本末尾(即为该 行重新分配存储空间)(并可删去文本中的原行),并修改 行表中该行的起始位置及行长信息。