数据结构(四)串
数据结构中的串

next[j] = max { k | 0<k<j 且使得 1…tk-1=tj-k+1…tj-1} 当集合不空 且使得t 1
首页
其他情况
上页 下页 退出
第四章
§4.4 串的应用
一、文本编辑 二、建立索引表
思考题: 思考题: 试写出判串S是否是回文的算法。 1、试写出判串S是否是回文的算法。 若串S= S=‘ STRING’以块链存储, 2、若串S=‘THIS IS A STRING’以块链存储,结点大小 链指针占4个字节, 32位 问存储密度是多少? 为4,链指针占4个字节,即32位,问存储密度是多少? 是两个但单链表存储的串,试设计一个算法, 3、若X和Y是两个但单链表存储的串,试设计一个算法, 找出X中第一个不在Y中出现的字符来。 找出X中第一个不在Y中出现的字符来。
首页
上页
下页
退出
第四章
§4.1 串类型的定义
三、C语言常用的字符串处理的标准函数: 语言常用的字符串处理的标准函数:
int strlen(char s); int strcmp(chars1,char s2); char strcpy(char to,char from); char strcat(char to,char from) 但在抽象数据类型定义的13种操作中, 13种操作中 但在抽象数据类型定义的13种操作中,串赋值 StrAssign、串复制StrCopy、串比较StrCompare、求串 StrAssign、串复制StrCopy、串比较StrCompare、 StrCopy StrCompare StrLength、串联接Concat以及求子串SubString Concat以及求子串SubString等 长StrLength、串联接Concat以及求子串SubString等6 种操作构成串类型的最小操作子集。 种操作构成串类型的最小操作子集。 例如,可利用判等、 例如,可利用判等、求串长和求子串等操作实现串 的定位函数 Index(S,T,pos) 和串的置换操作 Replace(S,T,V)。 。 换句话说,如果在高级程序设计语言中设有"串类 换句话说,如果在高级程序设计语言中设有 串类 的话, 种操作, 型"的话,提供的基本操作不能没有这 种操作,因为它 的话 提供的基本操作不能没有这6种操作 首页 上页 下页 退出 们不能通过其它串操作实现。 们不能通过其它串操作实现。
严蔚敏数据结构-第四章 串

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#)

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; }
数据结构四PPT课件

pos len
堆分配存储特点:仍用一组连续的存储单元来存放串,
但存储空间是在程序执行过程中动态分配而得。
思路:利用malloc函数合理预设串长空间。
有的语言允许对串常量命名,以使程序易读、易写。 【例】C++中,可定义串常量path
const char path[]="dir/bin/appl";
5
练1:串是由
字符组成的序
列,一般0记个或多个
为 S=’a1a2……an’
练2:现。有以下4个字符串:
a =‘BEI’
b =‘JING’ c = ‘BEIJING’
数据结构课程的内容
第4章 串 (String)
1. 定义 2. 逻辑结构 3. 存储结构 4. 运算规则 5. 实现方式
4.1 串类型的定义
4.2 串的表示和实现 4.3 串的模式匹配算法
4.1 串类型的定义
串即字符串,是由零个或多个字符组成的有限序列,是数据 元素为单个字符的特殊线性表。
记为: s =‘ a1 , a2 , …….. , an’ (n≥0 )
讨论:想存放超长字符串怎么办?——静态数组有缺陷!
改用动态分配的一维数组—— “堆”!
例:用顺序存储方式实现求子串函数SubString(&Sub, S, pos,
len)
将串S中从第pos个字符开始长度为len的字符序列复 制到串Sub中(注:串Sub的预留长度与Ssub, SString S, int pos, int len )
d
= ‘问B:EI①JI他NG们’各自的长度? a =3,b =4,c = 7,d=8
② a是哪个串的子串?在主串中的位置是多少?
数据结构第4章 串

/*若串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;
数据结构-第4章 串

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)代表单个字符,可以是字母、 数字或其它字符(包括空白符)。 串值:双引号括起来的字符序列。双引号不是 串的内容,只起标识作用。
《数据结构与算法》第四章-学习指导材料

《数据结构与算法》第四章串知识点及例题精选串(即字符串)是一种特殊的线性表,它的数据元素仅由一个字符组成。
4.1 串及其基本运算4.1.1 串的基本概念1.串的定义串是由零个或多个任意字符组成的字符序列。
一般记作:s="s1 s2 … s n""其中s 是串名;在本书中,用双引号作为串的定界符,引号引起来的字符序列为串值,引号本身不属于串的内容;a i(1<=i<=n)是一个任意字符,它称为串的元素,是构成串的基本单位,i是它在整个串中的序号; n为串的长度,表示串中所包含的字符个数,当n=0时,称为空串,通常记为Ф。
2.几个术语子串与主串:串中任意连续的字符组成的子序列称为该串的子串。
包含子串的串相应地称为主串。
子串的位置:子串的第一个字符在主串中的序号称为子串的位置。
串相等:称两个串是相等的,是指两个串的长度相等且对应字符都相等。
4.2 串的定长顺序存储及基本运算因为串是数据元素类型为字符型的线性表,所以线性表的存储方式仍适用于串,也因为字符的特殊性和字符串经常作为一个整体来处理的特点,串在存储时还有一些与一般线性表不同之处。
4.2.1 串的定长顺序存储类似于顺序表,用一组地址连续的存储单元存储串值中的字符序列,所谓定长是指按预定义的大小,为每一个串变量分配一个固定长度的存储区,如:#define MAXSIZE 256char s[MAXSIZE];则串的最大长度不能超过256。
如何标识实际长度?1. 类似顺序表,用一个指针来指向最后一个字符,这样表示的串描述如下:typedef struct{ char data[MAXSIZE];int curlen;} SeqString;定义一个串变量:SeqString s;这种存储方式可以直接得到串的长度:s.curlen+1。
如图4.1所示。
s.dataMAXSIZE-1图4.1 串的顺序存储方式12. 在串尾存储一个不会在串中出现的特殊字符作为串的终结符,以此表示串的结尾。
数据结构第四章串习题及答案

习题四串一、单项选择题1.下面关于串的的叙述中,哪一个是不正确的?()A.串是字符的有限序列 B.空串是由空格构成的串C.模式匹配是串的一种重要运算 D.串既可以采用顺序存储,也可以采用链式存储2.串是一种特殊的线性表,其特殊性体现在()。
A.可以顺序存储 B.数据元素是一个字符C.可以链接存储 D.数据元素可以是多个字符3.串的长度是指()A.串中所含不同字母的个数 B.串中所含字符的个数C.串中所含不同字符的个数 D.串中所含非空格字符的个数4.设有两个串p和q,其中q是p的子串,求q在p中首次出现的位置的算法称为()A.求子串 B.联接 C.匹配 D.求串长5.若串S=“softwa re”,其子串的个数是()。
A.8 B.37 C.36 D.9二、填空题1.含零个字符的串称为______串。
任何串中所含______的个数称为该串的长度。
2.空格串是指__ __,其长度等于__ __。
3.当且仅当两个串的______相等并且各个对应位置上的字符都______时,这两个串相等。
一个串中任意个连续字符组成的序列称为该串的______串,该串称为它所有子串的______串。
4.INDEX(‘DATAST RUCTU RE’,‘STR’)=________。
5.模式串P=‘abaabc ac’的next函数值序列为________。
6.下列程序判断字符串s是否对称,对称则返回1,否则返回0;如 f("abba")返回1,f("abab")返回0;int f((1)__ ______){int i=0,j=0;while(s[j])(2)___ _____;for(j--; i<j && s[i]==s[j]; i++,j--);return((3)___ ____)}7.下列算法实现求采用顺序结构存储的串s和串t的一个最长公共子串。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6
i=9 0 S t
slen
0 长度为4
பைடு நூலகம்
j=3
tlen
1、Brute Force算法: //在主串s中定位子串t,不存在返回-1 int Index(char s[],char t[]) { int i=0,j=0; int slen=strlen(s)-1;//s最大下标号 int tlen=strlen(t)-1; //t最大下标号 while(i<=slen && j<=tlen) if(s[i]==t[j]) { ++i; ++j;} else { i=i-j+1; j=0; } if(j>tlen) return i-tlen-1; else return -1; }
二、串的基本操作 对于串的基本操作,许多高级语言均提供了相应的运算或标准库函数来实现。 C/C++语言中常用的串运算如下: 定义下列几个变量: char s1*20+=“dirtreeformat”,s2*20+=“test.cpp”; char s3[30],*p; int result; (1)求串长(length) int strlen(char *s); //求串的长度 (2)串复制(copy) char *strcpy(char *to,char *from); 该函数将串from复制到串to中,并且返回一个指向串to的开始处的指针。 例如:strcpy(s3,s1); //s3=“dirtreeformat” (3)联接(concatenation) char *strcat(char *to,char *from) 该函数将串from复制到串to的末尾,并且返回一个指向串to的开始处的指针。 例如:strcat(s3,”/”) strcat(s3,s2); //s3=“dirtreeformat/test.cpp”
该点下标号返回
i 0 S t tlen
slen
0
j(tlen+1)
2、KMP算法
Donald E.Knuth,1938年出生于Wisconsin。1960年, 当他毕业于Case Institute of Technology数学系时,因 为成绩过于出色,被校方打破历史惯例,同时授予 学士和硕士学位。他随即进入大名鼎鼎的加州理工 学院数学系,仅用三年时间便取得博士学位,此时 年仅25岁。 毕业后留校任助理教授,28岁时升为副教授。30 岁时,加盟斯坦福大学计算机系,任教授。从31岁 那年起,他开始出版他的历史性经典巨著《The Art of Computer Programming》。他计划共写7卷,然而 仅仅出版三卷之后,已经震惊世界,使他获得计算 机科学界的最高荣誉图灵奖。此时,他年仅38岁! 后来,此书与牛顿的“自然哲学的数学原理”等一 起,被评为“世界历史上最伟大的十种科学著作” 之一。学过数据结构和编译原理的后都知道KMP算 法和LR(K)算法有多么不可思议,然而此书中这样的 算法比比皆是! 在计算机科学上,他主要是一位理论家。然而, 他在理论以外也同样做出惊人的成就。鼎鼎大名的 排版软件Tex,就是他的作品。1992年在斯坦福大学 荣誉退休。
例1、求子串 求子串的过程即为复制字符序列的过程,将串s中的第pos个字符开始的连续的len个 字符复制到串sub中。
void substr(string sub,string s,int pos,int len) { if(pos<0 || pos>strlen(s)-1 || len<0) return ; strncpy(sub,s+pos,len); } pos len
串中任意个连续字符组成的子序列称为该串的子串,包含子串 的串相应地称为主串。通常将子串在主串中首次出现时的该子串 的首字符在主串中的位置,定义为子串在主串中的序号(或位 置)。例如,设A和B分别为 A=“This is a string” B=“is” 则B是A的子串,A为主串。B在A中出现了两次,其中首次出现所 对应的主串位置是3。因此,称B在A中的序号(或位置)为3 特别地,空串是任意串的子串,串总是其自身的子串。 通常在程序中使用的串可分为两种:串变量和串常量。串常量 和整常数、实常数一样,在程序中只能被引用但不能改变其值, 即只能读不能写。通常串常量是由直接量来表示的,例如语句 cout<<“overflow”中“overflow”是直接量。但有的语言允许对串常 量命名,以使程序易读、易写。如C++中,可定义 const char path*+=“dir/bin/appl”; 这里path是一个串常量,对它只能读不能写。串变量和其它类型 的变量一样,其取值是可以改变的。
1、Brute Force算法: //在主串s中定位子串t,不存在返回-1 int Index(char s[],char t[]) { int i=0,j=0; int slen=strlen(s)-1;//s最大下标号 int tlen=strlen(t)-1; //t最大下标号 while(i<=slen && j<=tlen) if(s[i]==t[j]) { ++i; ++j;} else { i=i-j+1; j=0; } if(j>tlen) return i-tlen-1; else return -1; }
4.2.2 堆分配存储表示 这种存储表示的特点是,仍以一组地址连续的存储单元存 放串值字符序列,但它们的存储空间是在程序执行过程中动 态分配而得。所以也称为动态存储分配的顺序表。在C语言中,
利用动态存储管理函数,来根据实际需要动态分配和释放字
符数组空间。
4.2.3 串的链式存储结构 顺序串上的插入和删除操作不方便,需要移动大量的字符。 因此,可用单链表方式来存储串值,串的这种链式存储结构简 称为链串。 一个链串由头指针唯一确定。 这种结构便于进行插入和删除运算,但存储空间利用率太低。
当j 1时 0 next[ j ] f [ j 1] 1
j 模式串 f[j]
1 2 3 4 5 6 7 8 9 10 a b c a b c a c a b 0 0 0 1 2 3 4 0 1 2
next[j]
0 1 1 1 2 3 4 5 1 2
next[i]给出了当与模式串的第i个字符不匹配时,应该重新开始 比较的字符序号。如next[7]=4的意义为与模式串前6个比较成功, 但第7个不匹配,则下面同模式串第4个开始比较。 u v w a b c a b c x y a b…... a b c a b c a c a b
4.2 串的表示和实现
因为串是特殊的线性表,故其存储结构与线性表的存储结构类似。只不过由于 组成串的结点是单个字符。串有三种表示方法。
4.2.1定长顺序存储表示
定长顺序存储表示,也称为静态存储分配的顺序表。用一组连续的存储单元来存 放串中的字符序列。所谓定长顺序存储结构,是直接使用定长的字符数组来定义, 数组的上界预先给出: #define MAXSTRLEN 256 typedef char sstring[MAXSTRLEN]; sstring s; //s是一个可容纳255个字符的顺序串。 一般可使用一个不会出现在串中的特殊字符在串值的尾部来表示串的结束。例 如,C/C++语言中以字符‵\0′表示串值的终结,这就是为什么在上述定义中,串 空间最大值maxstrlen为256,但最多只能存放255个字符的原因,因为必须留一个 字节来存放‵\0′字符。若不设终结符,可用一个整数来表示串的长度,那么该 长度减1的位置就是串值的最后一个字符的位置。
s
sub
例2、串的定位index(s,t,pos) 在主串中取从第pos个字符起、长度和串t相等的子串和t比较,若相等,则求得函 数值为i,否则值增1直至S中不存在和串t相等的子串为止。
index(s, t, pos){ if(pos>0){ n=strlen(s); m=strlen(t); i=pos; while(i<n-m+1){ substr(sub,s,i,m); if(strcmp(sub,t)!=0) ++i; else return i; } } return -1; }
2、KMP算法 1)问题:s=“00000000000000000000000000001” t=“000000000001” 2)思路:每当一趟匹配过程中出现字符比较不等时,不在回溯i。
i
j i
前面一部分不比了
子串右滑一段
j
3)分析:
i
j
i
设同模式串p的第k个比较, •p的前k-1个字符号应该同从 主串s第i-1个倒数的k-1个字符 相同。 即:p1p2…pk-1=si-k+1si-k+2…si-1 •主串s从第i-1个倒数的k-1个 字符应该同子串第j个开始倒 数的k-1个字符也应该相同。 即:pj-k+1pj-k+2…pj-1=si-k+1si-k+2…si-1
当j 1时 0 next[ j ] f [ j 1] 1
j 模式串 f[j]
1 2 3 4 5 6 7 8 9 10 a b c a b c a c a b 0 0 0 1 2 3 4 0 1 2
next[j]
0 1 1 1 2 3 4 5 1 2
k
j
得到
p1p2…pk-1= pj-k+1pj-k+2…pj-1
4)失败函数f[j]:
i f [ j] 0
j 模式串 f[j]
使p1... pi p j i 1...p j 其它
1 2 3 4 5 6 7 8 9 10 a b c a b c a c a b 0 0 0 1 2 3 4 0 1 2