数据结构 第四章 串
计算机上的非数值处理掉的对象基本上是字符串数据。
在较早的程序设计语言中,字符串作为输入和输出的常量出现。
随着语言加工程序的发展,产生了字符串处理。
这样,字符串也就作为一种变量类型出现在越来越多的程序设计语言中,
同时也产生了一系列字符串的操作。
字符串一般简称串。
在汇编和语言的编译中源程序及目标程序都是字符串数据。
在事物处理程序中,顾客的姓名和地址以及货物的名称、产地和规格一般也是作为字符串数据处理的
信息检索、文字编辑系统、问答系统、自然语言翻译系统以及音乐分析程序等
都是以字符串数据作为处理对象的
4.1串的定义
4.1.1 串的基本概念
串(字符串):是零个或多个字符组成的有限序列。记作: S=“a1a2a3…”,其中S是串名,ai(1≦i≦n)是单个,可以是字母、数字或其它字符。
串值:双引号括起来的字符序列是串值。
串长:串中所包含的字符个数称为该串的长度。
空串(空的字符串):长度为零的串称为空串,它不包含任何字符。
空格串(空白串):构成串的所有字符都是空格的串称为空白串。
注意:空串和空白串的不同,例如“ ”和“”分别表示长度为1的空白串和长度为0的空串。
子串(substring):串中任意个连续字符组成的子序列称为该串的子串,包含子串的串相应地称为主串。
子串的序号:将子串在主串中首次出现时的该子串的首字符对应在主串中的序号,称为子串在主串中的序号(或位置)。
例如,设有串A和B分别是:
A=“这是字符串”,B=“是”
则B是A的子串,A为主串。B在A中出现了两次,其中首次出现所对应的主串位置是3。因此,称B在A中的序号为3 。
特别地,空串是任意串的子串,任意串是其自身的子串。
串相等:如果两个串的串值相等(相同),称这两个串相等。换言之,只有当两个串的长度相等,且各个对应位置的字符都相同时才相等。
通常在程序中使用的串可分为两种:串变量和串常量。
串常量和整常数、实常数一样,在程序中只能被引用但不能不能改变其值,即只能读不能写。通常串常量是由直接量来表示的,例如语句错误(“溢出”)中“溢出”是直接量。
串变量和其它类型的变量一样,其值是可以改变。
4.1.2 串的抽象数据类型定义
ADT String{数据对象:D = { ai|ai∈CharacterSet, i=1,2,…,n, n ≥0 }
数据关系:R = {<ai-1, ai>| ai-1, ai∈D, i=2,3,…,n }
基本操作:
StrAssign(t , chars)
初始条件: chars是一个字符串常量。
操作结果:生成一个值为chars的串t 。
StrConcat(s, t)
初始条件:串s, t 已存在。
操作结果:将串t联结到串s后形成新串存放到s中。
StrLength(t)
初始条件:字符串t已存在。
操作结果:返回串t中的元素个数,称为串长。
SubString (s, pos, len, sub)
初始条件:串s, 已存在, 1≦pos≦StrLength(s)且 0≦len≦StrLength(s) –pos+1。
操作结果:用sub返回串s的第pos个字符起长度为len的子串。
……
} ADT String
4.2 串的存储表示和实现
串是一种特殊的线性表,其存储表示和线性表类似,但又不完全相同。串的存储方式取决于将要对串所进行的操作。串在计算机中有3种表示方式:
◆ 定长顺序存储表示:将串定义成字符数组,利用串名可以直接访问串值。用这种表示方式,串的存储空间在编译时确定,其大小不能改变。
◆ 堆分配存储方式:仍然用一组地址连续的存储单元来依次存储串中的字符序列,但串的存储空间是在程序运行时根据串的实际长度动态分配的。
◆ 块链存储方式:是一种链式存储结构表示。
//1 串的联结操作
Status StrConcat ( StringType s, StringType t)
/* 将串t联结到串s之后,结果仍然保存在s中 */
{ int i, j ;if ((s.length+t.length)>MAX_STRLEN)Return ERROR ; /* 联结后长度超出范围 */for (i=0 ; i<t.length ; i++)s.str[s.length+i]=t.str[i] ; /* 串t联结到串s之后 */s.length=s.length+t.length ; /* 修改联结后的串长度 */return OK ;
}
//2 求子串操作
Status SubString (StringType s, int pos, int len, StringType *sub)
{ int k, j ;if (pos<1||pos>s.length||len<0||len>(s.length-pos+1))return ERROR ; /* 参数非法 */sub->length=len-pos+1 ; /* 求得子串长度 */for (j=0, k=pos ; k<=leng ; k++, j++)sub->str[j]=s.str[i] ; /* 逐个字符复制求得子串 */return OK ;
}
4.2.2 串的堆分配存储表示
实现方法:系统提供一个空间足够大且地址连续的存储空间(称为“堆”)供串使用。可使用C语言的动态存储分配函数malloc()和free()来管理。
特点是:仍然以一组地址连续的存储空间来存储字符串值,但其所需的存储空间是在程序执行过程中动态分配,故是动态的,变长的。
//串的堆式存储结构的类型定义
typedef struct
{ char *ch; /* 若非空,按长度分配,否则为NULL */int length; /* 串的长度 */
}HString ;
1 串的联结操作
Status Hstring *StrConcat(HString *T, HString *s1, HString *s2)
/* 用T返回由s1和s2联结而成的串 */
{ int k, j , t_len ; if (T.ch) free(T); /* 释放旧空间 */t_len=s1->length+s2->length ;if ((p=(char *)malloc(sizeof((char)*t_len))==NULL){ printf(“系统空间不够,申请空间失败 !\n”) ; return ERROR ; }for (j=0 ; j<s->length; j++) T->ch[j]=s1->ch[j] ; /* 将串s复制到串T中 */for (k=s1->length, j=0 ; j<s2->length; k++, j++) T->ch[j]=s1->ch[j] ; /* 将串s2复制到串T中 */free(s1->ch) ; free(s2->ch) ; return OK ;
}
4.2.3 串的链式存储表示
串的链式存储结构和线性表的串的链式存储结构类似,采用单链表来存储串,结点的构成是:
◆ data域:存放字符,data域可存放的字符个数称为结点的大小;
◆ next域:存放指向下一结点的指针。
若每个结点仅存放一个字符,则结点的指针域就非常多,造成系统空间浪费,为节省存储空间,考虑串结构的特殊性,使每个结点存放若干个字符,这种结构称为块链结构。如图4-1是块大小为3的串的块链式存储结构示意图。
串的块链式存储的类型定义包括:
//⑴ 块结点的类型定义
#define BLOCK_SIZE 4
typedef struct Blstrtype
{ char data[BLOCK_SIZE] ;struct Blstrtype *next;
}BNODE ;
//(2) 块链串的类型定义
typedef struct{ BNODE head; /* 头指针 */int Strlen ; /* 当前长度 */}Blstring ;
4.3 串的模式匹配算法
模式匹配(模范匹配):子串在主串中的定位称为模式匹配或串匹配(字符串匹配) 。模式匹配成功是指在主串S中能够找到模式串T,否则,称模式串T在主串S中不存在。
模式匹配的应用在非常广泛。例如,在文本编辑程序中,我们经常要查找某一特定单词在文本中出现的位置。显然,解此问题的有效算法能极大地提高文本编辑程序的响应性能。
模式匹配是一个较为复杂的串操作过程。迄今为止,人们对串的模式匹配提出了许多思想和效率各不相同的计算机算法。介绍两种主要的模式匹配算法。
//算法实现/* 采用顺序存储方式存储主串s和模式t, */
/* 若模式t在主串s中从第pos位置开始有匹配的子串,*/
/* 返回位置,否则返回-1 */
int IndexString(StringType s , StringType t , int pos )
{ char *p , *q ;int k , j ;k=pos-1 ; j=0 ; p=s.str+pos-1 ; q=t.str ; /* 初始匹配位置设置 *//* 顺序存放时第pos位置的下标值为pos-1 */while (k<s.length)&&(j<t.length){ if (*p==*q) { p++ ; q++ ; k++ ; j++ ; } else { k=k-j+1 ; j=0 ; q=t.str ; p=s.str+k ; }/* 重新设置匹配位置 */}if (j==t.length)return(k-t.length) ; /* 匹配,返回位置 */else return(-1) ; /* 不匹配,返回-1 */
}
该算法简单,易于理解。在一些场合的应用里,如文字处理中的文本编辑,其效率较高。 该算法的时间复杂度为O(n*m) ,其中n 、m分别是主串和模式串的长度。通常情况下,实际运行过程中,该算法的执行时间近似于O(n+m) 。
4.3.2 模式匹配的一种改进算法
#define Max_Strlen 1024
int next[Max_Strlen];
int KMP_index (StringType s , StringType t) /* 用KMP算法进行模式匹配,匹配返回位置,否则返回-1 *//*用静态存储方式保存字符串, s和t分别表示主串和模式串 */
{ int k=0 , j=0 ; /*初始匹配位置设置 */while (k<s.length)&&(j<t.length{ if ((j==-1)|| (s. str[k]==t.str[j])) { k++ ; j++ ; } else j=next[j] ;}if (j>= t.length) return(k-t.length) ; else return(-1) ;
}
void next(StringType t , int next[]) /* 求模式t的next串t函数值并保存在next数组中 */
{ int k=1 , j=0 ; next[1]=0;while (k<t.length){ if ((j==0)|| (t.str[k]==t.str[j])) { k++ ; j++; if ( t.str[k]!=t.str[j] ) next[k]=j;else next[k]=next[j];}else next[j]=j ; }
}
数据结构 第四章 串相关推荐
- C语言数据结构-第四章 串-电大同步进度
第四章 串 字符串是计算机处理的最基本的非数值数据.字符串是一种特定的线性表,其特殊性就在于组成线性表的每个元素就是一个单字符. 本章给出: l 串的基本概念 l 串的 ...
- (王道408考研数据结构)第四章串-第一节:串的定义和基本操作及存储结构
文章目录 一:串基本概念 (1)串的定义 (2)相关术语 (3)串的基本操作 二:串的比较 三:字符集编码 四:串的存储结构 (1)串的顺序存储 (2)串的链式存储 一:串基本概念 (1)串的定义 串 ...
- 王道数据结构课代表 - 考研数据结构 第四章 串-KMP(看毛片算法) 究极精华总结笔记(C版本)
本篇博客是考研期间学习王道课程 传送门 的笔记,以及一整年里对数据结构知识点的理解的总结.希望对新一届的计算机考研人提供帮助!!! 关于对 串 章节知识点总结的十分全面,涵括了<王道数据结构 ...
- 王道408数据结构——第四章 串(KMP算法)
一.串的定义和实现 字符串简称串,是由零个或多个字符组成的有限序列,一般记为S=′a1a2⋅⋅⋅an′S='a_1a_2···a_n'S=′a1a2⋅⋅⋅an′,n称为串的长度. 串中任意多个连 ...
- (王道408考研数据结构)第四章串-第二节:串的模式匹配算法(朴素和KMP)
串的匹配是一个非常重要的话题,我们在Word中经常使用的搜索功能所反映的就是串的匹配问题,相应的算法也是层出不穷,各有优缺点,本节主要涉及两种算法:朴素算法和KMP算法 在讲解之前,有几个术语需要掌握 ...
- c语言实现bf算法的定位函数,数据结构c语言版严蔚敏清华大学出版社第四章串.ppt...
数据结构c语言版严蔚敏清华大学出版社第四章串 模式匹配(定位) 设有主串S和子串T(将S称为目标串,将T称为模式串),在主串S中,从位置start开始查找,如若在主串S中找到一个与子串T相等的子串,则 ...
- 《数据结构》-第四章 串、数组和广义表(习题)
第四章 串.数组和广义表练习题 本章考点较少易于掌握,对于串的重点考点为串的模式匹配算法:数组的主要考点为数组下标与存储地址计算和特殊矩阵的压缩存储方法:针对广义表的考点主要为在广义表中取原子项(表) ...
- 数据结构c语言版第四章题库,严蔚敏《数据结构(c语言版)习题集》答案第四章 串...
严蔚敏<数据结构(c语言版)习题集>答案第四章 串 第四章 串 4.10 void String_Reverse(Stringtype s,Stringtype &r)//求s的逆 ...
- 第四章 串(数据结构与算法)
第四章 串[数据结构与算法] 配套资源下载 第4章串 4.1应用实例 4.2串及其运算 4.2.1串的基本概念 4.2.2 串的基本运算 4.3串的存储结构及实现 4.3.1 定长顺序串 4.3.2 ...
- 《数据结构》天勤和王道 第四章 串
<数据结构>天勤和王道 第四章 串 天勤部分 1. 串的基础 1.1 逻辑结构 1.2 存储结构 1.3 赋值操作 1.4 串比较 1.5 串连接 1.6 求子串 1.7 清空串 2. K ...
最新文章
- 《LeetCode力扣练习》第160题 相交链表 Java
- linux系统清除日志,如何清除Linux系统日志
- php中include和require,在PHP中include和require到底有什么区别呢?
- JS加密算法简单分析
- [Redux/Mobx] redux和flux的区别是什么?
- Android之ViewDragHelper
- CentOS 7 利用Docker搭建Showdoc文档管理系统
- 钢琴块2电脑版_云上钢琴学生端电脑版|云上钢琴学生端 V2.3.1 最新PC版 下载_当下软件园...
- .net下samus Mongo-Cshap 引擎中的find原生查询
- NetBeans Weekly News: #125-Nov 17,2010
- hive使用适用场景_ 如何将Hive与HBase整合联用
- 微信公众号-推送模板消息
- proteus 安装包以及破解汉化
- PTA2017年天梯赛题目整理
- M26模块TCP透传数据流程笔记
- 兰州工业学院有计算机专业,兰州工业学院计算机协会
- java获取b站动态列表地址,java获取B站弹幕文件的两种方案
- html无边框网格,table没有网格线_html/css_WEB-ITnose
- webpack-dev-server代理请求配置
- QQ群头像 微信群头像 多图合并框架实现