数据结构与算法 (C++语言版) 第4章 串.

Slides:



Advertisements
Similar presentations

Advertisements

3 的倍数的特征 的倍数有 : 。 5 的倍数有 : 。 既是 2 的倍数又是 5 的倍数有 : 。 12 , 18 , 20 , 48 , 60 , 72 , , 25 , 60 ,
2.8 函数的微分 1 微分的定义 2 微分的几何意义 3 微分公式与微分运算法则 4 微分在近似计算中的应用.
2.5 函数的微分 一、问题的提出 二、微分的定义 三、可微的条件 四、微分的几何意义 五、微分的求法 六、小结.
数据结构的引入. 通讯录管理 社团机构管理 校园导航管理 通讯录管理 社团机构管理 校园导航管理.
《高等数学》(理学) 常数项级数的概念 袁安锋
初中数学八年级下册 (苏科版) 10.4 探索三角形 相似的条件(2).
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
第九章 字符串.
第四章 串 2018/11/13.
C语言高级编程(第四部分) 字符串 北京大学 信息科学技术学院.
数据结构——串 1/15.
第四章 串和数组(一) 1/.
走进编程 程序的顺序结构(二).
辅导课程六.
第4章 串 4.1 串的基本概念及其抽象数据 4.2 串的存储结构 4.3 串类 4.4 串的模式匹配算法.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
计算机数学基础 主讲老师: 邓辉文.
4.1 串的抽象数据类型的定义 4.2 串的表示和实现 4.3 串的模式匹配算法.
第二章 Java语言基础.
动态规划(Dynamic Programming)
顺序表的插入.
从zval看PHP变量
第一章 函数与极限.
本节内容 字符编码 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言程序设计 主讲教师:陆幼利.
学习目标 1、什么是字符集 2、字符集四个级别 3、如何选择字符集.
顺序表的删除.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
VB与Access数据库的连接.
5.1 串的基本概念 5.2 串的存储结构 5.3 串的基本运算 5.4 模式匹配 5.5 串在文本编辑中的应用
数 据 结 构 刘家芬 Sept 2012.
单链表的基本概念.
顺序查找.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
项目二:HTML语言基础.
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第六章 Excel的应用 一、Excel的单元格与区域 1、单元格:H8, D7, IV26等 2、区域:H2..D8, HS98:IT77
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
§6.7 子空间的直和 一、直和的定义 二、直和的判定 三、多个子空间的直和.
3.16 枚举算法及其程序实现 ——数组的作用.
第四章 串 £4.1 串的定义 £4.2 串的顺序存储结构 £4.3 串的链式存储结构 £4.4 串的应用—文本编辑
1.2 子集、补集、全集习题课.
第4课时 绝对值.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
学习任务三 偏导数 结合一元函数的导数学习二元函数的偏导数是非常有用的. 要求了解二元函数的偏导数的定义, 掌握二元函数偏导数的计算.
第一章 绪论 1.1 引言 1.2 逻辑结构和存储结构 1.3 算法.
学习目标 1、了解基本运算符 2、运算符优先级.
2.6 字符型数据 一、 字符常量 1、字符常量的定义 用一对单引号括起来的单个字符,称为字符常量。 例如,‘A’、‘1’、‘+’等。
第15讲 特征值与特征向量的性质 主要内容:特征值与特征向量的性质.
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
_03宽字符与Unicode编程 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
实验目的:掌握数据的顺序存储结构及它们在计算机中的操作。 实验内容:
第六章 Excel的应用 五、EXCEL的数据库功能 1、Excel的数据库及其结构 2、Excel下的数据排序 (1)Excel的字段名行
第四章 串 String
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第十七讲 密码执行(1).
第十二讲 密码执行(上).
使用ADO访问数据库 李宝智 BonizLee 课程 10564A
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
§4.5 最大公因式的矩阵求法( Ⅱ ).
顺序结构程序设计 ——关于“字符串”和数值.
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
学习目标 1、什么是列类型 2、列类型之数值类型.
Presentation transcript:

数据结构与算法 (C++语言版) 第4章 串

现实世界中的实体有多种形式,如数值、文字符号序列、图形、图像、声音等,其中文字(符号)序列称为字符串,简称串。串是一种常用的数据结构,用于描述非数值的简单信息,它在现实世界中屡见不鲜,如人名、产品名、事物名称、车牌号、文献、源程序等。从数据元素间的逻辑关系看,串是线性表,但从操作方式与种类看,它与线性表有许多不同。在计算机中,串被认为是一种特殊的线性表——元素为文字符号的线性表。由于现实问题中经常使用串,所以对串应选择合适的存储结构,并提供灵活多样的基本操作。

串的逻辑结构 基本概念 串(string)是由零个或多个字符构成的有限序列,一般记为s=‘s1s2…sn’(n≥0)。其中,s是串名,用单引号括起来的字符序列是串的值,但单引号本身并不属于串,si(1≤i≤n)为一个字符,字符是计算机可识别的任意符号(字母、数字或其他符号)。 串的长度:串中字符的数目n。 空串:零个字符的串,其长度为零。 空白串:由一个或多个空格组成的串,其长度为串中空格字符的个数。 子串:串中任意个连续的字符组成的子序列。 主串:包含子串的串相应地称为主串。

串的逻辑结构 字符在串中的位置:字符在序列中的序号。 串相等:当且仅当这两个串的值相等,即两个串的长度相等,并且各个对应位置的字符都相等。 通常,在程序中使用的串可分为两类:串变量和串常量。串变量和其他类型的变量一样,其取值是可改变的。串常量和常数一样,在程序中只能被引用但不能改变其值,即只能读不能写。

例4-1 假设a、b、c、d为如下的4个串:a=‘Guang’,b=‘Zhou’,c=‘GuangZhou’,d=‘Guang Zhou’。它们的长度分别为5、4、9、10;并且a和b都是c和d的子串,a在c和d中的位置都是1,而b在c中的位置是6,在d中的位置是7;a、b、c、d彼此都不相等。 显然,若某串的长度为n,则在该串中,长度为1的子串的个数为n,长度为2的子串的个数为n1,……,长度为i的子串的个数为n(i1),所以长度为n的串中子串总数(包括空串与自身)为1+ =1+ 。串的抽象数据类型定义见以下ADT 。

例4-1

例4-1

例4-1

串的逻辑结构 串的大小比较 字符的大小 在计算机中,每个字符都有一个唯一的数值表示——字符编码(字符内码),字符间的大小关系就定义为它们的代码之间的大小关系。字符编码可有多种,对英文字母和符号,ASCII码是最常见的一种。本书用字符的ASCII码之间的大小关系代表相应字符的大小关系。 ASCII码即美国信息交换标准编码,是长度为8位二进制符号,所以最多能编28=256个不同的字符。但ASCII码中规定,最高位为1的码代表一些特殊的字符(或命令),所以ASCII码有效的字符编码为128个,其包括英文大、小写字母,数字0~9及一些常用符号(计算机键盘上的字符键)。在字符和数字中,空格编码最小,其次是数字(按0~9的次序)、大写字母(按A~Z的次序)、小写字母(按a~z的次序)等。

串的逻辑结构 对于汉字,它们的大小关系也按编码大小确定。汉字的编码也有几种,如我国内地用的国标码(GB2312),我国台湾地区用的Big5等。GB2312(国标码)是针对汉字的16位二进制编码,所以最多能编216=65536个不同的码,足以代表新华字典中所有的汉字。GB2312将汉字分为两级编码,分别称一级字库和二级字库。一级字库包括了日常用的大多数汉字,其汉字的国标码之间的大小关系,与对应的汉语拼音构成的串的大小关系一致(在新华字典中,排在较前面的字,它的国标码也较小)。而二级字库中的汉字码之间的大小关系,与对应汉字的笔画数目的大小关系一致。 要在一个系统中混合使用多种文字,需要一种统一的编码系统,它可以将各种文字的基本字符在同一空间内编码,UniCode就是这样一种编码。

串的逻辑结构 字符串间的大小关系 有了字符大小的定义,就可考虑串的大小关系了。设X与Y是两个串,X=‘x1 x2…xm’,Y=‘y1y2…yn’,则它们之间的大小关系定义如下。 ① 当m=n且x1=y1, …, xm=yn时,称X=Y。 ② 当下列条件之一成立时,称X<Y: i.m<n,且xi=yi,i=1, 2, …, m; ii.存在某一个k≤MIN(m, n),使得xi=yi,i=1, 2, …, k–1,xk<yk。 ③ 当不属于情况①与②时,称X>Y。这种方法定义的串的大小关系,也称字典序。下面给出几个例子说明此定义:‘abac’与‘abac’,相等(=);‘we’与‘web’,前者小于后者(属于情况i);‘mouth’与‘move’,前者小于后者(属于情况ii)

串的存储结构 与线性表类似,串也有两种基本的存储结构:顺序结构与链式结构。考虑到存储效率与算法实现的方便性,串多采用顺序存储结构。 顺序存储 串的顺序存储结构简称为顺序串。与顺序表类似,顺序串用一组地址连续的存储单元来存储串中的字符序列,可用高级程序语言中字符数组来实现。按存储分配的不同可将顺序串分为静态存储分配的顺序串和动态存储分配的顺序串。

串的存储结构 链式存储 用单链表方式存储串的值,这种存储结构简称为链串,链串分为两种形式。①非压缩形式。一个链表结点只存储一个字符。为了操作方便,设置一个指向首元素结点的指针和一个指向尾元素结点的指针,同时仍设置串长度值字段。这种结构类似于线性表的链式存储,其优点是操作方便,但存储利用率很低。②压缩形式。一个链结点存储多个字符,实质上是一种连续存储与链式相结合的结构。这种结构能提高存储利用率,但其对应的操作实现起来较为复杂。例如,在对串长度进行修改时,常涉及链结点的增加与删除操作,如果仅允许不满的结点出现在最后一个结点上,则需要经常移动字符,但如果允许不满结点出现在其他位置,则又会造成串的表示不一致的问题,也会使操作实现复杂化。

串函数与串的类定义 常用的C++串函数 C++的串库(string.h)中提供了许多字符串的操作函数,几个常用的C++字符串函数及其使用方法如下。 假设已有以下定义语句:

串函数与串的类定义 (1)串拷贝函数 char *strcpy(char *s1, const char *s2),将字符串s2复制到字符串数组s1中,返回s1的值。 char *strncpy(char *s1, const char *s2, size_tn)将字符串s2中最多n个字符复制到字符串数组s1中,返回s1的值。 例如:

串函数与串的类定义 (2)串连接函数 char *strcat(char *s1, const char *s2),将字符串s2添加到字符串s1的后面,s2的第一个字符重定义s1的null终止符,返回s1的值。 char *strncat(char *s1, const char *s2, size_tn)将字符串s2中最多n个字符添加到字符串s1的后面,s2的第一个字符重定义s1的null终止符,返回s1的值。 例如:

串函数与串的类定义 (3)串比较函数 int strcmp(const char *s1, const char *s2),比较字符串s1和字符串s2。函数在s1等于、小于或大于s2时,分别返回0、小于0或者大于0的值。 int strncmp(const char *s1, const char *s2, size_tn)比较字符串s1中的n个字符和字符串s2。函数在s1等于、小于或大于s2时,分别返回0、小于0或者大于0的值。 例如:

串函数与串的类定义 (4)串长度函数 size_strlen(const char *s),确定字符串长度,返回null终止符之前的字符数。例如: (5)串中字符定位

串函数与串的类定义 串的类定义 C++语言提供的丰富的串函数库有很强的串操作功能,但对于一般使用者来说,其使用起来不是很方便。在一些高级程序设计语言中,两个串可用“+”连接,可用赋值号把一个串赋值给另一个串,两个串的比较可直接用“<”、“>”、“==”等比较运算符。这里可使用重载操作符的办法,使C++语言中的一些运算符具有新的功能。以下程序给出串的类定义。

串函数与串的类定义

例4-2 求子串算法substr。

例4-3 串以链式形式存放的算法。

例4-3

例4-4 将node串q所指结点中第p个字符后的第i个有效字符送至r。q指针如下图所示。

例4-4

串模式匹配 这里介绍一个很重要的操作——StrStr的实现,该操作与Index(S,T,pos)一样,也叫串模式匹配。给定两个串T与P:T=‘t0t1…tn–1’,P=‘p0p1…pm–1’,其中0<m≤n,将在T中寻找最先出现的一个与P相同的子串的过程称为串模式匹配,称T为目标串(主串),P称为模式串(子串),下面介绍的StrStr( )函数就属于串模式匹配。 串模式匹配在符号处理中占有十分重要的地位,它是基于规则匹配的逻辑推理的(如Prolog语言的目标执行过程、专家系统中的推理机),所以它的效率十分重要。这里先介绍一种简单的匹配算法,它的时间复杂度较高,然后介绍它的一种改进算法。

串模式匹配 简单串模式匹配算法 以下程序是一种带回溯的匹配算法。首先将子串P视为从主串T中第1个字符起与T对齐,从头起依次比较对应字符;若全部对应相等,则表明已匹配成功,终止;否则,将P视为从T中第2个字符起与T对齐,再从头比较对应字符;过程与前类似,如此进行,直至某次匹配成功,或某次T中无足够的剩余字符与P对齐(不能匹配,失败)。

串模式匹配 实现时,设置三个指示器i,j,ii,它们的含义如下。 i:指向主串T中当前参加比较的字符。起始时,指向T的首字符,之后,每比较一次,后移一步,一趟匹配失败时,回溯到该趟比较起点的下一位置。 j:指向子串P中当前参加比较的字符。起始时,指向T的首字符,之后,每比较一次,后移一步,一趟匹配失败时,回溯到P的首字符处。 ii:记录每趟比较在主串T中的起点,每趟比较后,后移一步。

串模式匹配

串模式匹配 下面分析此算法的时间复杂度。显然,此算法的主要工作是do循环,它的循环次数与目标串及模式串相关,所以时间复杂度是个随机量。最理想的情况是,第一趟就得到匹配,此时的循环次数为n(即子串s的长度),而最坏的情况是不存在匹配,且每趟匹配过程都在比较完子串s中最后一个字符时才发现不能匹配,此种情况的循环次数是(m–n+1)×n,这里m为主串的长度。显然,n越大,此式的值越小。当n<< m时,此式约等于m×n。

串模式匹配 无回溯的匹配算法 在上面介绍的匹配算法中,某趟匹配失败时,下一趟的匹配相当于将子串P后移1位再从头与主串中对应字符进行比较,即相当于i指示器回溯到上趟(最近失败的一趟)匹配的起点的下一个位置,这样,主串中每个字符都要与子串中的第1个字符对应一次,再向后比较。因此,主串中每个字符参加比较的次数最多可达n次(n为子串长度),因此时间复杂度为O(nm)。那么,能否使目标串中每个字符只参加一次比较呢?也就是说,能否不回溯i指示器?回答是肯定的。这个问题是由D.E.Knoth与V.R.Pratt和J.H.Morris同时解决的,所以有的文献也称这种思想的串匹配算法为KMP算法。

串模式匹配 i指示器之所以可不回溯,是因为重新开始一趟匹配时,可利用上趟匹配的结果。一般而言,一个无回溯匹配法的关键问题是,在匹配过程中一旦发现pj与ti不等,应能确定出从P中的哪个字符起与ti(或ti+1)对齐继续往下比较。这里记这个字符为pk,显然k<j,且对不同的i,k也不同。Knoth等人发现这个k值仅仅依赖于子串P的前i个字符的构成,而与主串T无关。这是个令人鼓舞的发现,它是实现无回溯的关键。可用一个函数next表示j与k的这种对应关系,它是仅与子串有关的函数,其含义是,在匹配过程中,一旦发现一对不等的字符(设为pj与ti),若next(j)=k(k≥0),则下次的比较应从P中的pk起与T中的ti对齐往下进行;若next(j)<0,则P中任何字符不必再与ti进行比较,下次比较从P的首字符起与ti+1对齐往下进行。next(j)的取值,应首先保证使匹配过程无遗漏(即不放过任何可能的匹配),其次,应使P串向后滑动尽可能长的距离。函数next( )称为失败函数。

串模式匹配 下面假定对给定的子串,它的next函数已确立,则串模式匹配算法可描述为以下程序的形式,它也是KMP算法的基本部分。

串模式匹配 以上程序中,用一维数组next[ ]表示失败函数next(),变量i只增不减,其初值为0,在循环中一直保持i<n,所以i加1的语句i++至多执行n次,又因为next[j]<j,且l≤j≤m,故语句j=next[j]至多执行m次,由于循环中只存在分别含有i++与j=next[j]的两个互斥分支,故循环次数不超过MAX(m, n),因此算法的时间复杂度为O(MAX(m, n))。通常m<n,故时间复杂度为O(n)。

串的应用——文本编辑 在办公室自动化、企业的现代化管理等许多领域中,文本编辑(程序)正发挥着越来越大的作用。文本编辑的实质是修改字符数据的形式或格式,如Microsoft Word,汉字信息处理系统(激光排版系统)等。虽然这些系统的功能不太一样,但基本操作一般都包括串的查找、插入和删除等操作,主要用于源程序的输入和修改,报刊和书籍的编辑排版及公文书信的起草与润色等。通常,整个文本可看成是一个字符串,其中,页是文本的子串,行又是页的子串。例如,以下程序便可看成是一个文本串:

串的应用——文本编辑 在该程序的输入过程中,由文本编辑程序为文本串建立相应的页表和行表,即建立各子串的存储映射。页表的每一项给出了页号和该页的起始行号,而行表的每一项则指示每一行的行号、起始地址和该行子串的长度。每输入的一行都可作为一个新的字符串加到文本中,串的值放在文本区中,行号、串值的存储地址及串长度则登记到表中。通过这个行表,新的一行可放到文本工作区的任何一个自由区中。设下图所示的文本串只占一页,且起始行号为200,则该文本串的行表如图所示。

串的应用——文本编辑

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

本 章 总 结 学习要点 本章主要介绍串的基本概念、基本运算、静态存储结构与动态存储结构,以及基本操作的实现方法,串操作的综合应用程序设计。主要学习要点如下:① 串的逻辑结构定义和串的连接、求子串、定位、置换、插入、删除等基本运算的功能;② 串的静态存储和动态存储的基本思想和实现方法;③ 串操作在文本编辑、文本格式化处理中的应用。

本 章 总 结 基本要求 (1)深入领会串运算的定义和基本算法以及综合应用程序设计; (2)知道(字符)串的有关术语、逻辑结构、特点以及与线性表的区别; (3)弄清串的连接,求子串、模式匹配、置换等基本运算的功能,并能灵活应用串的这些基本运算; (4)弄清顺序串和链串紧缩格式的主要优缺点,非紧缩格式的优缺点; (5)了解串及其运算在文本编辑及文本格式化中的应用。

本 章 总 结 重点与难点 重点是:求子串、定位、置换基本运算(操作)的实现算法。难点是:串的综合应用程序设计。