数据结构-第4章 串
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
查找:p->data=‘a’ && p->next->data=‘b’ p
…
a
bቤተ መጻሕፍቲ ባይዱ
…
4.1.6 串的链式存储表示
替换
s
p
…
xa
bz
…
qy
s
…x
y
z
…
4.1.6 串的链式存储表示
void Repl(LinkStrNode *s){ LinkStrNode *p=s->next,*q;
int find=0; while (p->next!=NULL && find==0){
串抽象数据类型=逻辑结构+基本运算 ADT String{
数据对象: D ={ ai|ai∈ElemSet, i=1,2,…,n,n≥0 } 数据关系: R ={<ai-1, ai>|ai-1,ai∈D, i=2,4,…,n }
4.1.2 串的抽象数据类型定义
基本操作:
StrAssign(&s,cstr):将字符串常量cstr赋给串s,即生成其值等 于cstr的串s。 StrCopy(&s,t):串复制。将串t赋给串s。 StrEqual(s,t):判串相等。若两个串s与t相等则返回真;否则返 回假。 StrLength(s):求串长。返回串s中字符个数。 DelStr(s,i,j):删除。从串s中删去从第i(1≤i≤n)个字符开 始的长度为j的子串,并返回产生的新串。 StrInsert(s1,i,s2):插入。在串s1第i个位置插入字符串s2,并返回 新串。
为模式匹配或串匹配(字符串匹配) 。
目标串s 是子串吗?
模式串t
模式匹配
成功是指在目标串s中找到一个模式串t,t是s
的子串,返回t在s中的位置。
不成功则指目标串s中不存在模式串t,t不是s
的子串,返回-1。
4.2.1 Brute-Force算法
Brute-Force简称为BF算法,亦称简单匹配算法。 采用穷举的思路。
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)
} StringType ;
4.1.4 串的静态顺序存储表示
(1) 串的联结操作
StringType StrConcat ( StringType s, StringType t){ /* 将串t联结到串s之后,结果仍然保存在s中 */ int i; if ((s.length+t.length)>MaxSize) return 0; /* 联结后长度超出范围 */ /*strcat(s.str,t.str);*/ for (i=0 ; i<t.length ; i++) s.str[s.length+i]=t.str[i] ; /* 串t联结到串s之后 */ s.length=s.length+t.length ; /* 修改联结后的串长度 */ return s;}
{ if (s.data[i]==t.data[j])
//继续匹配下一个字符
{ i++;
j++;} //主串和子串依次匹配下一个字符
else //主串、子串指针回溯重新开始下一次匹配
{ i=i-j+1; //主串从下一个位置开始匹配
j=0; flag=0;
} //子串从头开始匹配
}
if (j>=t.length) return(i-j);
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
设计顺序串上实现串比较运算Strcmp(s,t)的算法
若S>T返回真,反之返回假。
不能使用串S T的长度进行比较。例如:
S="ab" < T="abcd"
S="abcd" <T= "xy"
解题思路:
S与T逐个取元素对比,若二者相等则指针同 步后移一位,直至两串同时结束,返回真;反之 循环结束,返回假。
}LinkStrNode ;
4.1.6 串的链式存储表示
【单选题】用带头结点的单链表来表示串s,则串s 为空串的条件是( ) A.s->next==NULL B.s==NULL C.s->next==s D.s->next->next==NULL
4.1.6 串的链式存储表示
【例】在链串中,设计一个算法把最先出现的 子串“ab”改为“xyz”。
free(s1->ch) ; free(s2->ch) ; return 1; }
4.1.6 串的链式存储表示
串的链式存储结构和线性表的串的链式存储结 构类似,采用单链表来存储串:
data域:存放字符,data域可存放的字符个数称 为结点的大小; next域:存放指向下一结点的指针。
4.1.6 串的链式存储表示
若每个结点仅存放一个字符,则结点的指针域 就非常多,造成系统空间浪费。
为节省存储空间,考虑串结构的特殊性,使每 个结点存放若干个字符,这种结构称为块链结构。
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
LiSi
Boy
…
结点大小为4的链串
#define MaxSize 4
typedef struct StrNode
链存储方式:是一种链式存储结构表示。
4.1.4 串的静态顺序存储表示
#define MaxSize 100 //最大存储量,无分号
#typedef char ElemType ;
typedef struct
{ ElemType str[MaxSize]; //静态,数组形式
int length;
//串长度
T->length=s1->length+s2->length +1; 为最后的\0预留位置
if ((T->ch=(char *)malloc(sizeof((char)* T->length))==NULL)) { printf(“系统空间不够,申请空间失败 !\n”) ;
return 0 ; }
4.1.5 串的动态顺序存储表示
(1) 串的联结操作
for (j=0 ; j<s1->length; j++) T->ch[j]=s1->ch[j] ; /* 将串s复制到串T中 */
for (k=s1->length, j=0 ; j<s2->length; k++, j++) T->ch[k]=s2->ch[j] ; /* 将串s2复制到串T中 */
//返回匹配的第一个字符的下标
else return(-1); //模式匹配不成功
}
4.2.1 Brute-Force算法
int BFIndex(SqString s,SqString t)
{ int i=0, j=0,k;
while (i<s.length && j<t.length)
{ k=i;
if (s.data[i]==t.data[j])
//继续匹配下一个字符
{ i++;
j++;} //主串和子串依次匹配下一个字符
else //主串、子串指针回溯重新开始下一次匹配
{ i=k+1; //主串从下一个位置开始匹配
j=0; flag=0;
} //子串从头开始匹配
}
if (j>=t.length) return(k); //返回匹配的第一个字符的下标
} ADT Stack
4.1.3 串的存储表示和实现
串的存储方式取决于将要对串所进行的操作。 在计算机中有3种表示方式:
静态顺序存储表示:将串定义成字符数组, 利用串名可以直接访问串值。用这种表示方式, 串的存储空间在编译时确定,其大小不能改变。
4.1.3 串的存储表示和实现
动态顺序存储方式:仍然用一组地址连续的存 储单元来依次存储串中的字符序列,但串的存 储空间是在程序运行时根据串的实际长度动态 分配的。
4.1.5 串的动态顺序存储表示
typedef struct {
char *ch; //若非空,按长度分配,否则为null int length; // 串的长度 } HString ;
4.1.5 串的动态顺序存储表示
(1) 串的联结操作
Hstring* StrConcat(HString *T, HString *s1, HString *s2){ /* 用T返回由s1和s2联结而成的串 */ int k, j ; if (T->ch) free(T->ch); /* 释放旧空间 */
find=1;
} else p=p->next;
}}
作业
设计如下算法:char* StrRelace(char T[], char P[], char S[]),将T中第一次出现的与P相等的 子串替换为S(串S和P的长度不一定相等),并 分析时间复杂度。
4.2 串的模式匹配
模式匹配(模范匹配):子串在主串中的定位称
串的长度(或串长):串中所含字符的个数, 含零个字符的串称为空串。
第4章 串的基本概念
串相等: 当且仅当两个串的长度相等并且各个对应位 置上的字符都相同时,这两个串才是相等的。 【例】:“abcd” ≠ “abc”
“abcd” ≠ “abce” 注:所有空串是相等的。
第4章 串的基本概念
子串:一个串中任意个连续字符组成的子序 列(含空串)称为该串的子串。 【例】 “abcde”的子串有: “”、“a”、“ab” 、“abc”、“abcd” 和“abcde”等
4.1.2 串的抽象数据类型定义
RepStr(s,i,j,t):替换。在串s中,将第i(1≤i≤n)个字符开 始的j个字符构成的子串用串t替换,并返回产生的新串。 DispStr(s):串输出。输出串s的所有元素值。 Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串 。 SubStr(s,i,j,sub):求子串。返回串s中从第i(1≤i≤n)个字 符开始的、由连续j个字符组成的子串,由sub返回。
//查找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;
真子串是指不包含自身的所有子串。
4.1 串的类型定义
子串的序号:将子串在主串中首次出现时的该 子串的首字符对应在主串中的序号,称为子串 在主串中的序号(或位置)。 【例】 A=“abcdefbbcd”,B=“bcd”,B在A中的 序号为2。 特别地,空串是任意串的子串,任意串是其自 身的子串。
4.1.2 串的抽象数据类型定义
{ char data[MaxSize] ;
struct StrNode *next;
}LinkStrNode ;
18 ∧
4.1.6 串的链式存储表示
串的块链式存储的类型定义包括:
s
A
B
…
Z∧
结点大小为1的链串
typedef struct StrNode
{
char data ;
struct StrNode *next;
4.1.4 串的静态顺序存储表示
(2) 求子串操作
int SubString (StringType s, int pos, int len, StringType *sub){ /*用sub返回串s的第pos个字符起长度为len的子串。*/ int k, j ; if (pos<1||pos>s.length||len<0||len>(s.length-pos+1)) return 0 ; /* 参数非法 */ sub->length=len ; /* 求得子串长度 */ for (j=0; j<len ; j++) sub->str[j]=s.str[pos -1+j] ; /* 逐个字符复制求得子串 */ return 1 ;