湖经数据结构 4-串
数据结构4-串

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
v v
串是一种特殊的线性表 串与一般线性表的区别:
™ 串的数据元素约束为字符集; ™ 串的基本操作通常针对串的整体或串的一个部分进行。
v
为何要单独讨论“串”类型?
™ 字符串操作比其他数据类型更复杂(如拷贝、连接操作) ™ 程序设计中,处理对象很多都是串类型。
5
串的抽象数据类型定义
ADT String{ 数据对象:D={ai|ai∈CharacterSet,i=1,2,…,n;n≥0} 数据关系:S={< ai-1 , ai >| ai-1, ai ∈D, i = 2,…,n} 基本操作: StrAssign(&T,chars) StrLength(S) SubString(&Sub,S,pos,len) StrCopy(&T,S) StrCompare(S,T) Concat(&T,S1,S2) Index(S,T,pos) StrEmpty(S) Replace(&S,T,V) StrInsert(&S,pos,T) StrDelete(&S,pos,len) ……
数据结构-4 串

数据结构-4 串数据结构 4 串在计算机科学中,数据结构是组织和存储数据的方式,以便能够有效地进行操作和访问。
今天,咱们来聊聊数据结构中的“串”。
什么是串呢?简单来说,串就是由零个或多个字符组成的有限序列。
这就好比我们日常说的一句话、一篇文章中的一段文字,都是串的具体表现形式。
串在计算机中的应用非常广泛。
比如说,在文本编辑中,我们输入的每一行文字都可以看作是一个串;在网络通信中,传输的各种信息也常常以串的形式存在;在数据库中,存储的字符数据也可以理解为串。
为了更好地处理串,计算机科学家们设计了各种各样的操作和算法。
首先是串的存储结构。
常见的有两种:顺序存储和链式存储。
顺序存储就像是把一串字符一个挨着一个地放在连续的内存空间里。
这样的好处是可以快速地随机访问串中的任意字符,但缺点是在插入或删除字符时可能需要大量的移动操作。
链式存储则是通过节点把字符连接起来,每个节点存储一个字符以及指向下一个节点的指针。
这种方式在插入和删除操作时比较方便,但随机访问的效率相对较低。
接下来,咱们聊聊串的比较操作。
比较两个串是否相等是很常见的需求。
这可不是简单地看看两个串长得一不一样,还得考虑字符的顺序和数量。
常见的比较方法有逐个字符比较,从串的开头一个一个比下去,直到发现不同或者其中一个串结束。
再说说串的模式匹配。
这是一个很重要的操作,比如说要在一篇长文章中找到某个特定的关键词或者短语,这就用到了模式匹配算法。
其中,著名的有朴素模式匹配算法和 KMP 算法。
朴素模式匹配算法的思路很直接,就是从主串的开头开始,逐个与模式串进行匹配,如果匹配不成功就将模式串往后移动一位继续匹配。
这个算法简单易懂,但效率不是很高,特别是在主串和模式串长度较长时。
KMP 算法则通过对模式串的预处理,计算出一个 next 数组,利用这个数组可以在匹配不成功时更有效地移动模式串,从而提高匹配的效率。
除了上面说的这些,串还有很多其他的操作,比如串的连接、子串提取、串的替换等等。
4 串

}
4.3.2 KMP 算法
由D.E.Knuth、J.H.Morris和V.R.Pratt共同提出了一个改进算法, 消除了Brute-Force算法中串s指针的回溯,完成串的模式匹配。时 间复杂度为O(s.curlen+t.curlen),这就是Knuth-Morris-Pratt算法, 简称KMP 算法。 为了进一步讨论KMP算法,让我们首先讨论一个例子。假设 s=‚abacabab‛,t=‚abab‛,第一次匹配过程如下图所示:
1)j 退回到某个j=next[j]时有 si = tj,则指针各增1,继续匹配;
2)j 退回至 j=-1,此时令指针各增l,即下一次比较 si+1和 t0 。
KMP算法的描述如下: #define MaxLen <最大串的长度> //定义最大串存储空间 int Index_KPM(string s,string t) { int i,j,next[MaxLen]; GetNext(t,next); //先求得模式串的next函数值 i=0; //指向串s的第1个字符 j=0; //指向串t的第1个字符 while((i<s.curlen)&&(j<t.curlen)) if ((j==-1)||(s.str[i]==t.str[j])) { ++i; ++j;} else j=next[j]; //i不变,j回退 if (j>=t.curlen) return (i-t.curlen); //匹配成功 else return(0); //匹配失败 }
如:s=〃I’m a student〃的长度为13。 注意:在C语言中,用单引号引起来的单个字符与单个字符的 串是不同的, 如s1=‘a’与s2=〃a〃两者是不同的,s1表示字 符,s2表示字符串。 当两个串的长度相等且各对应位臵上的字符都相同时,这两个 串是相等的。 串中任意个连续字符组成的序列称为该串的子串。包含子串的 串被称为主串。 例如, "com"、"om"、"a" 和 "man" 都是 "commander" 的子串 。子串在主串中的位臵是指子串中第一个字符在主串中的位臵序 号。如子串"man"在主串"commander"中的位臵为4。
2022年湖北经济学院计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)

2022年湖北经济学院计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)一、选择题1、下列排序算法中,占用辅助空间最多的是()。
A.归并排序B.快速排序C.希尔排序D.堆排序2、设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主存储, a11为第一元素,其存储地址为1,每个元素占一个地址空间,则a85的地址为()。
A.13B.33C.18D.403、以下数据结构中,()是非线性数据结构。
A.树B.字符串C.队D.栈4、在用邻接表表示图时,拓扑排序算法时间复杂度为()。
A.O(n)B.O(n+e)C.O(n*n)D.O(n*n*n)5、在下列表述中,正确的是()A.含有一个或多个空格字符的串称为空格串B.对n(n>0)个顶点的网,求出权最小的n-1条边便可构成其最小生成树C.选择排序算法是不稳定的D.平衡二叉树的左右子树的结点数之差的绝对值不超过l6、已知关键字序列5,8,12,19,28,20,15,22是小根堆(最小堆),插入关键字3,调整后的小根堆是()。
A.3,5,12,8,28,20,15,22,19B.3,5,12,19,20,15,22,8,28C.3,8,12,5,20,15,22,28,19D.3,12,5,8,28,20,15,22,197、下列关于无向连通图特性的叙述中,正确的是()。
Ⅰ.所有的顶点的度之和为偶数Ⅱ.边数大于顶点个数减1 Ⅲ.至少有一个顶点的度为1A.只有Ⅰ B.只有Ⅱ C.Ⅰ和Ⅱ D.Ⅰ和Ⅲ8、设X是树T中的一个非根结点,B是T所对应的二叉树。
在B中,X是其双亲的右孩子,下列结论正确的是()。
A.在树T中,X是其双亲的第一个孩子B.在树T中,X一定无右兄弟C.在树T中,X一定是叶结点D.在树T中,X一定有左兄弟9、每个结点的度或者为0或者为2的二叉树称为正则二叉树。
n个结点的正则二叉树中有()个叶子。
A.log2nB.(n-1)/2C.log2n+1D.(n+1)/210、分别以下列序列构造二叉排序树,与用其他三个序列所构造的结果不同的是()。
数据结构第4章串B教学ppt

《算法导论》
Thomas H. Cormen等编著的经典算法教材,深 入讲解了算法设计和分析的方法,包括串的模式 匹配等算法。
MOOC课程
中国大学MOOC、Coursera等在线教育平台上 提供了大量与数据结构和算法相关的课程,可以 系统地学习相关知识和技能。
压缩串处理技术
针对大规模文本数据,研究压缩串处理技术可以减少存储 空间占用,提高处理效率,是未来发展的重要方向之一。
串的并行处理技术
利用并行计算技术加速串的处理过程,提高处理效率,是 未来研究的热点之一。需要解决并行化算法设计、并行计 算框架选择等问题。
拓展学习资源推荐
1 2 3
《数据结构(C语言版)》
Sunday算法
Sunday算法是一种简单且高效的字符串匹配算法,其核心思 想是当发现不匹配的字符时,直接跳过主串中当前字符之前 的所有字符,将模式串与主串的下一个字符进行比较。
03
串的应用举例
文本编辑中的串操作
01
02
03
字符串匹配
在文本编辑中,经常需要 查找或替换特定的字符串, 这可以通过串的匹配操作 实现。
可以使用数组下标和字 符串截取函数`substr()` 实现串的截取,如`char ch = str[2];`或 `std:string sub = str.substr(2, 4);`。
Python语言实现串的基本操作
串的定义与初始化
在Python中,串使用引号(单引号、双 引号或三引号)进行定义和初始化,如`s = 'hello'`或`s = "hello"`。的比较
数据结构-4 串

数据结构-4 串数据结构 4 串在计算机科学中,数据结构是组织和存储数据的方式,以便能够有效地进行操作和处理。
其中,串(String)是一种非常常见且重要的数据结构,它在众多的应用中都发挥着重要的作用。
串,简单来说,就是由零个或多个字符组成的有限序列。
我们日常生活中接触到的各种文本,比如一篇文章、一条短信、一个网页的标题等等,在计算机中都可以用串来表示。
串有其独特的特点。
首先,它具有有限长度。
这意味着串中包含的字符数量是有限的,不能无限增长。
其次,串中的字符通常来自某个特定的字符集,比如常见的ASCII 字符集或者Unicode 字符集。
再者,串中的字符是按照一定的顺序排列的,这个顺序是有意义且不可随意更改的。
为了在计算机中有效地存储和操作串,有多种不同的实现方式。
一种常见的方式是使用字符数组。
我们可以定义一个足够大的字符数组来存储串中的字符。
这种方式直观且简单,但在进行串的修改操作(如插入、删除)时,可能会比较麻烦,因为需要移动大量的字符来腾出空间或者填补空缺。
另一种方式是使用指针和动态分配内存。
通过动态分配内存,可以根据串的实际长度来灵活地分配所需的存储空间。
这样在处理长度变化较大的串时,效率会更高,但也需要注意内存的释放,以避免内存泄漏的问题。
在对串进行操作时,有许多常见的基本运算。
比如串的连接,就是将两个串拼接在一起形成一个新的串。
还有串的比较,判断两个串是否相等,或者哪个串在字典序上更大。
此外,还有子串的提取,从一个串中取出一部分连续的字符形成新的串。
串的应用场景十分广泛。
在文本编辑软件中,对输入的文本进行处理和存储就离不开串。
在数据库系统中,存储和检索字符串类型的数据也需要对串进行有效的管理。
在编程语言中,字符串的处理也是常见的操作,比如字符串的格式化输出、字符串的查找和替换等等。
举个例子,当我们在搜索引擎中输入关键词时,搜索引擎会将我们输入的关键词作为一个串,然后在其庞大的数据库中进行匹配和查找,找到与这个串相关的网页和信息。
4 串

由样本串t求出next值的算法如下:
void getnext(char p[], int next[],int m) { int j,i;
next[1]=0;
for (j=2; j<=m; j++) { i=next[j-1];
while (i>0&&p[i]!=p[i-1])
i=next[i]; next[j]=i+1; } ruturn ; } }
(3)灵活运用串这种数据结构解决一些综合 应用问题。
a
i=9
j=1 i=10→17
第十趟
文本 a b a a b a a c c a b a a b c a b c
abaabca
j=1→8
在i=17, j=8时匹配成功, 返回10。
int index(char T[], char P[], int n, int m) { int i=1,j=1;
while ((i<n-m+1) && (j<m)) { if (T[i]==P[j]) /*继续匹配下一个字符*/ { i++; j++; } /*主串和子串依次匹配下一个字符*/ else /*主串、子串指针回溯重新开始下一次匹配*/ { i=i-j+2; /*主串从下一个位置开始匹配*/ j=1; /*子串从头开始匹配*/ } } if (j>m) retunr i-m+1; /*返回匹配的第一个字符的下标*/ else return 0; /*模式匹配不成功*/
结论:模式匹配过程中没有回溯。
第一趟
文本 a b a a b a a c c a b a a b c a b c
数据结构4

S4连接S1,结果‘QRSTUVWXYZ’,S1全部被截断。
Data Structure
2013-6-27
Page 14
Status Concat(SString &T,SString S1,SString S2){
// 以T返回由S1和S2联接而成的新串,若未截断,返回TRUE,否则FALSE If(S1[0]+S2[0]<=MAXSTRLEN){ //未截断
2013-6-27
Page 23
基础知识题
简述空串和空格串(或称空格符串)的区别。 设s = ‘I AM A STUDENT’, t = ‘GOOD’, q = ‘WORKER’。 求: StrLength(s) StrLength(t) SubString(s,8,7) SubString(t,2,1) Index(s,'A') Index(s,t), Replace(s, 'STUDENT',q), Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))
if ( pos<1 || pos>s[0] || len<0 || len > s[0]-pos+1) return ERROR;
Sub[1..len] = S[pos..pos+len-1];
Sub[0] = len; return OK; } // SubString
Data Structure
Data Structure 2013-6-27 Page 7
DestroyString (&S) 初始条件:串 S 存在。 操作结果:串 S 被销毁。 StrEmpty (S) 初始条件:串 S 存在。 操作结果:若 S 为空串,则返回 TRUE,否则返回 FALSE。 StrCompare (S, T) 初始条件:串 S 和 T 存在。 操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若 S<T,则返回值<0。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
教学内容
串
1、串的相关概念; 2、串的存储结构; 3、串的各种运算的实现。 教学要求 1、理解串的基本操作的定义,并能利用这些 基本操作来实现串的其它各种操作的方法; 2、熟练掌握在顺序存储结构上实现串的各种 操作的方法; 3、了解串操作的应用方法和特点。计算Βιβλιοθήκη 科学与技术学院 软件工程系 邓沌华
1、将一个字符串常量赋值给串s
void StrAssign ( HString &s,char cstr[ ] ) { int i; for( i=0;cstr[i]!=„\0’;i++ ) s.ch[i]=cstr[i];
s.length=i; }
计算机科学与技术学院 软件工程系 邓沌华
2、将串t赋值给串s void StrCopy( HString &s,HString &t ) { int i;
若相等,则继续逐个比较后继字符; 否则从文本t的第二个字符起重新与模式p的第一 个字符进行新一轮比较;
依次类推,若匹配成功,返回p在t中首次出现的 位置;
否则返回函数值0。
计算机科学与技术学院 软件工程系 邓沌华
B-F算法
顺序串存储结构定义:
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1]; 考虑用0号单元存放串的长度
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1];
考虑用0号单元存放串的长度
计算机科学与技术学院 软件工程系 邓沌华
二、串的堆分配存储 仍以一组地址连续的存储单元存放串值字符序列, 但它们的存储空间是在程序执行过程中动态分配而 得。 串的堆分配存储结构定义:
计算机科学与技术学院 软件工程系 邓沌华
KMP算法 KMP算法是由D.E.Knuth,J.H.Morris和V.R.Pratt 命名的算法,是他们同时发现的。 KMP算法是对B-F算法的改进,将其时间复杂度 由O(mn)改为O(m+n)。 改进方法:每当一趟匹配过程中出现字符不相等
时,利用模式p和已经得到的‚部分匹配‛的结果 将
a b …… x
struct snode *next;
};
计算机科学与技术学院 软件工程系 邓沌华
第四章 串
串的相关定义
串的存储 串的运算 串的匹配
计算机科学与技术学院 软件工程系 邓沌华
基于顺序串的相关运算的实现
typedef struct sqstring
{ char *ch;
int length; }HString;
if(s.length!=t.length) same=0; else { for(i=0;i<s.length;i++) if(s.ch[i]!=t.ch[i])
{ same=0; break; }
return same; }
计算机科学与技术学院 软件工程系 邓沌华
4、返回由串s和t连接在一起形成的新串
7 8 9 a c c a b a a b c a b c i=6,j=6不等 向右滑行,从i=6,j=3继续 || ? i=8,j=5不等 a b a a b c 向右滑行,从i=8,j=2继续 ? i=8,j=2不等 我们要解决的问 a b a a b c 从i=8,j=1继续 题是: ? i=8,j=1不等 模式p向右‚滑 a b a a b c 从i=9,j=1继续 行‛多少呢? ? i=9,j=1不等 从i=10,j=1继续 a b a a b c 失败链接值 第6轮成功 1 a || a 2 b || b 3 a || a 4 a || a 5 b || b 6 a ? c ||
str.length=0; if(i<=0‖i>s.length‖j<0‖i+j-1>s.length) return str; for(k=i-1;k<i+j-1;k++)
str.ch[k-i+1]=s.ch[k];
str.length=j; return str; }
计算机科学与技术学院 软件工程系 邓沌华
计算机科学与技术学院 软件工程系 邓沌华
失败链接值:在执行匹配比较的过程中,一旦出现
p[j] ≠t[i],则找到一个满足k<j且最大的整数k,使得
模式p中p[j]前面的k-1个字符(p[j-k+1]…p[j-1])与 p中开头的前k个(p[1]p[2]…p[k-1])字符相同,则称k 为字符p[j]的失败链接值。例如: p=“abaabc”中第6 个字符的失败链接值为3.
HString Concat(HString &s,HString &t)
{ HString str;
int i; str.length=s.length+t.length; for(i=0;i<s.length;i++) str.ch[i]=s.ch[i];
for(i=0;i<t.length;i++)
str.length=s.length-j+t.length; return str;
}
计算机科学与技术学院 软件工程系 邓沌华
第四章 串
串的相关定义
串的存储 串的运算 串的匹配
计算机科学与技术学院 软件工程系 邓沌华
串的匹配
模式匹配:假设t和p是两个给定的串,在t中寻
找与p相同的子串的过程称为模式匹配。 正文(text):一般称t为正文; 模式(pattern):一般称p为模式;
c=„speak‟
串长 5 ,且为a的子串 ; d=„ing‟ 串长 3 ,且为b 的子串 ; e=„ „ 空白串,串长为1;
列‘a1a2a3……an’。 串长:串中字符的个数:n。
空串:串中无字符:n=0。 空格串:串中只有空格符。
子串:串中任一连续的子序列。 f=„‟ 主串:包含子串的串。
空串,串长为0。
if(i<=0‖i>s.length‖j<0‖i+j-1>s.length)
for(k=0;k<i-1;k++) str.ch[k]=s.ch[k];
return str;
for(k=0;k<t.length;k++) str.ch[i+k-1]=t.ch[k]; for(k=i+j-1;k<s.length;k++) str.ch[t.length+k-j]=s.ch[k];
?
p: a b a a b c p中各个字符的失败链接值与t无关,只依赖于p 本身。因此可在进行匹配前预先确定p中每个字 符的失败链接值。 设:用数组next[maxsize]依次存放模式p中各个 字符的失败链接值。 计算机科学与技术学院 软件工程系
邓沌华
首先置next[1]= 0,然后依次求出next[2],next[3],……。现假设 在求next[j](1<=j<maxsize)之前,next[1],next[2],...next[j-1]已 依次被求出,如果next[j-1]=k,那么应有:
模式 p 向右‚滑动‛一段距离后,不需回溯 j ,继 续 例:t=“abaabaaccabaabcabc” 进行比较。 p=“abaabc” 若采用B-F算法将在第 10 轮匹配成功。
计算机科学与技术学院 软件工程系 邓沌华
例:t=“abaabaaccabaabcabc” p=“abaabc” KMP
例2:p=“abaabc”,计算各字符的失败链接值。
j p[j] next[j]
1 a 0
2 b 1
3 a 1
4 a 2
5 b 2
6 c 3
计算机科学与技术学院 软件工程系 邓沌华
引入失败链接值的意义
观察p串:a b a a b c t:
p: t:
a b a a b a a c c a b
a b a a b c a b a a b a a c c a b
计算机科学与技术学院 软件工程系 邓沌华
第四章 串
串的相关定义
串的存储 串的运算 串的匹配
计算机科学与技术学院 软件工程系 邓沌华
串的存储 一、定长顺序存储——顺序串 串的 定长顺序存储:类似于线性表的顺序存储,用 一组地址连续的存储单元存放串值,为串分配固定 长度的存储区。 顺序串存储结构定义:
for( i=0;i<t.length;i++ )
s.ch[ i ]=t.ch[ i ];
s.length=t.length;
}
计算机科学与技术学院 软件工程系 邓沌华
3、判断两个串s和t是否相等
int StrEqual (HString &s,HString &t)
{ int same=1,i;
6、返回从串s中删除从第i个字符开始的 由连续j个字符组成的子串后产生的新串。
HString DelStr(HString &s,int i,int j) { HString str; int k; str.length=0;
if(i<=0‖i>s.len‖j<0‖i+j>s.length+1)
return str; for(k=0;k<i-1;k++) str.ch[k]=s.ch[k]; for(k=i+j-1;k<s.length;k++)
int Index(SString T,SString P,int pos) { //返回子串P在主串T中第pos个字符之后的位置,若不存在,则函数 值为0 i=pos; j=1; while(i<=T[0]&&j<=P[0]) { if(T[i]==P[j]) {++i; ++j;} else {i=i-j+2; j=1;} } if(j>P[0]) return i-P[0]; else return 0;}