计算机数据结构第四章串
严蔚敏数据结构-第四章 串
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的子串
数据结构第四章 串
数据结构第四章串在数据结构的世界里,串是一种非常基础且重要的结构。
它看似简单,却在很多实际的程序设计和应用中发挥着关键作用。
串,简单来说,就是由零个或多个字符组成的有限序列。
这就好比我们日常生活中的一句话、一段文字或者一个密码。
从存储方式上来看,串可以采用顺序存储和链式存储两种方式。
顺序存储就像是把一串珠子穿在一根线上,珠子依次排列,位置固定。
在计算机中,我们可以用一个连续的数组来存储串中的字符。
这种方式简单直观,访问速度快,但存在着一些局限性。
比如说,如果我们事先不知道串的长度,可能会造成存储空间的浪费或者不足。
相比之下,链式存储则更加灵活。
它就像把珠子用链条串起来,每个珠子(也就是字符)都有一个指针指向下一个珠子。
这样,即使在插入或删除字符时,也不需要像顺序存储那样进行大量的数据移动。
但是,链式存储的缺点是访问速度相对较慢,因为需要通过指针依次查找。
接下来,让我们看看串的一些基本操作。
串的比较是经常会用到的操作。
比较两个串的大小,不能像比较数字那样简单地直接比较,而是要从串的第一个字符开始,逐个字符进行比较。
如果在某个位置上的字符不同,那么 ASCII 码值大的那个串就更大;如果前面的字符都相同,但是一个串先结束了,那么长度短的串就更小。
串的连接也是常见的操作。
想象一下把两段绳子接在一起,就形成了一个更长的绳子。
串的连接也是类似的道理,把两个串首尾相连,形成一个新的串。
但在实际操作中,要注意存储空间的分配,确保有足够的空间来容纳连接后的串。
还有串的子串操作。
比如说,从一篇文章中截取一段文字,这就是获取一个子串。
在程序中,我们需要明确指定子串的起始位置和长度,才能准确地获取到所需的部分。
串的模式匹配更是一个重要的应用。
这就像是在一篇长篇小说中寻找特定的关键词或者短语。
最常见的模式匹配算法有朴素模式匹配算法和 KMP 算法。
朴素模式匹配算法比较直接,就是从主串的开头逐个字符与模式串进行匹配。
而 KMP 算法则通过对模式串进行预处理,利用已经匹配的部分信息,减少不必要的比较,从而提高匹配的效率。
数据结构——第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; }
数据结构 第四章 串
4.1 4.2
串类型的定义 串的表示和实现
4.2.1 定长顺序存储表示 4.2.2 堆分配存储表示 4.2.3 串的块链存储表示
第四章 串
4.1 串类型的定义
一、串的基本概念 定义:字符串是 n ( 0 ) 个字符的有限序列
记作 S = “c1c2c3…cn”
其中:
S 是串名字 “c1c2c3…cn”是串值 ci 是串中字符 n 是串的长度
4.1 串类型的定义
一、串的基本概念
串中任意个连续字符组成的子序列称为该串的
子串,包含子串的串相应地称为主串。
子串在主串中首次出现时的该子串的首字符 对应的主串中的序号,定义为子串在主串中的
序号(或位置)
例如,设A和B分别为 A=“This is a string” B=“is”
4.1 串类型的定义
提取子串的算法示例
pos = 3, len = 3 infini ty
pos = 6, len = 4 infini ty
fin
len S[0]-pos+1
超出 len > S[0]-pos+1
合法参数条件: Pos>=0, Pos<=S[0], Len>=0
len <=S[0]-pos+1
求子串的过程即为复制字符序列的过程,将串S中的 第pos个字符开始长度为len的字符复制到串T中。
1、串的插入的动态实现过程 s.length+ t.length
SA
l o v el y
pos Tl o
t.length
vely
g irl!
t.length
1、串的插入的动态实现过程 s.length+ t.length
数据结构第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;
数据结构--第四章 串
则:串s3是s1的子串, s1是s3的主串;
串s2不是s1的子串
5
串的概念
串的位置:字符在序列中的序号为 该字符在串中的位置。子串在主 串中的位置则以子串的第一个字 符在主串中的位置来表示。特别 地,空串是任意串的子串,任意 串是其自身的子串。 例如: s1=’I have a dog’; s3=’dog’ 则:子串s3在s1中的位置为匹配(求子串位置) 第一趟:
i=1
a b a b c a b c a c b a b
J=1
a b c
31
串基本操作的实现 —— 串的模式匹配(求子串位置) 第一趟:
i=3
a b a b c a b c a c b a b
J=3
a b c
32
串基本操作的实现 —— 串的模式匹配(求子串位置) 第二趟:
D A T A S T R U C T U R E
D U R
A S C E
T T T
A R U
19
串的存储结构——动态存储结构
串的动态存储方式采用链式存储结构 和堆存储结构两种形式: (一) (二) 块链存储 堆结构
20
串的动态存储结构 ——块链存储的引入
用单链表存放串,每个结点仅存储一个字符, 每个结点的指针域所占空间比字符域所占空间 要大得多。定义如下: typedef struct node{ char ch; struct node *next;
9
串的基本操作定义
⑵ 判等函数:Equal(s,t)
若s和t相等, 则返回函数值(即运算结 果)1, 否则返回函数值 0。s和t可以是 非空串,也可以是空串。 例如, 执行Equal (a,b) 后, 值为0。 执行Equal (‘abc’,‘abc’) 后, 值为1。
数据结构(C语言版)第4章串
第4章串串:限定数据元素类型的线性表。
1 逻辑结构1.1 定义位串:数据元素属于{0,1}ASCII码串: 数据元素属于ASCII码字符集。
数字串:数据元素属于整数集合2 顺序串///////////////////////////////// // 项目路径:7动态顺序串/////////////////////////////////2.2 构造/析构(测试函数Test1)template <class T>String<T>:: String( ){ m_Data=NULL; m_Size=m_Length=0; }template <class T>String<T>::String(T a[], int n){ m_Size = m_Length = n;m_Data = new T[m_Size];if(!m_Data) throw "内存不够,上溢";for(int i=0; i<m_Length; i++)m_Data[i]=a[i];}template <class T>String<T>::String(String &s) // 拷贝构造函数{ m_Size = m_Length = s.m_Length;m_Data = new T[m_Size];if(!m_Data) throw "内存不够,上溢";for(int i=0; i<m_Length; i++)m_Data[i]=s.m_Data[i];}template <class T>String<T>:: ~String( ){ delete []m_Data; }2.3 比较(测试函数Test2)// 重载<template <class T>bool String<T>::operator<(String &s){ for(int i=0; i<m_Length && i<s.m_Length; i++) { if(m_Data[i]<s.m_Data[i]) return true;if(m_Data[i]>s.m_Data[i]) return false;}if(m_Length<s.m_Length) return true;return false;}// 重载==template <class T>bool String<T>::operator==(String &s){ for(int i=0; i<m_Length && i<s.m_Length; i++) if(m_Data[i]!=s.m_Data[i]) return false; if(m_Length==s.m_Length) return true;return false;}2.4 取子串、连接(测试函数Test3)// 取子串template <class T>String<T> String<T>::Substr(int pos,int len) { if(pos+len>m_Length) // 预防子串长度越界len=m_Length-pos;String<T> s;s.m_Length=s.m_Size=len;s.m_Data = new T[s.m_Size];if(!s.m_Data) throw "内存不够,上溢";for(int i=0; i<len; i++)s.m_Data[i]=m_Data[pos+i];return s;}// 连接stemplate <class T>void String<T>::Concat(String s){ if(m_Length+s.m_Length > m_Size) // 空间不够ReNew(m_Length+s.m_Length);for(int i=0; i<s.m_Length; i++)m_Data[m_Length+i] = s.m_Data[i];m_Length += s.m_Length;}// 重新分配串的存储空间template <class T>void String<T>::ReNew(int size){ T *p=new T[size]; // 重新申请空间 m_Size=size;for(int i=0; i<m_Length; i++) // 数据迁移p[i]=m_Data[i];delete []m_Data; // 释放原串空间 m_Data = p;}2.5 插入、删除(测试函数Test4)// 第i个位置上插入stemplate <class T>void String<T>::Insert(int pos, String s){ if(m_Length+s.m_Length > m_Size) // 空间不够 ReNew(m_Length+s.m_Length);for(int i=m_Length-1; i>=pos; i--) // 向后移位 m_Data[i+s.m_Length] = m_Data[i];for(i=0; i<s.m_Length; i++)m_Data[pos+i] = s.m_Data[i];m_Length += s.m_Length;}// 删除子串template <class T>void String<T>::Delete(int pos,int len){ for(int i=pos+len; i<m_Length; i++) // 向前移位 m_Data[i-len] = m_Data[i];m_Length -= len;}2.6 顺序串的评价优点:访问子串方便,缺点:空间大小不灵活,插入、删除费时。
数据结构-第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,用一个不会出现在串中的特殊字符在串值的尾部 来表示串的结束.例如,C语言中以字符`\0′表示 串值的终结. 2,用s[0]存放串的实际长度,串值存放在 s[1]~s[MAXSIZE]. 3,类似顺序表,另设一个整数表示串长: typedef struct{ char ch[maxstrlen]; int length; }sstring;
即最坏情况下的时间复杂度是O(n*m).
2.改进后的模式匹配算法
一种对BF算法做了很大改进的模式匹配算法是克努特(Knuth),莫里 斯(Morris)和普拉特(Pratt)同时设计的,简称KMP算法. (1)KMP算法的思想 (2)next函数
(3) KMP算法 int StrIndex_KMP(char *s,char *t,int pos) /*从串s的第pos个字符开始找首次与串t相等的子串*/ { int i=pos,j=1,slen,tlen; while (i<=s[0] && j<=t[0] ) /*都没遇到结束符*/ if (j==0||s[i]==t[j]) { i++; j++; } else j=next[j]; /*回溯*/ if (j>t[0]) return i-t[0]; /*匹配成功,返回存储位置*/ else return –1; }
示例
第一趟
第二趟
第三趟
第四趟
4.4 串的应用举例
1,文本编辑 2,信息检索 在常用的高级语言及开发环境中,大多系统本身都提供了串的 类型及大量的库函数,用户可直接使用,这样会使算法的设计 和调试更方便容易,可靠性更高.
习题四
4.1 设s='I AM A STUDENT',t='GOOD',q='WORKER' 求: strlength(s),substring(s,8,7),index(s,'A'),Replace(s,' STUDENT',q),concat(substring(s,6,2),concat(t,subst ring(s,7,8))) 4.2 从顺序串r中删除其值等于ch的所有字符,要求以较高 效率实现. 4.3令 s='aaab',t='abcabaa',u='abcaabbabcabaacbacba'. 试分别求出它们的next值 .
《数据结构》--第四章 串
4.3 串的基本运算
4、插入子串: insert(s,s1,i) 在串s的第i个位置插入串s1。 5、删除子串: delete(s,i,j) 从串s的第i个位置开始,连续删除j个 字符。 6、子串定位: match(s,s1) 返回子串s1在串s中第一次出现的位置。 7、子串替换: replace(s,s1,i,j) 将串s中从第i个位置开始的长度 为j的子串用串s1来替换。
1. 串连接
串连接就是把两个串连接在一起,其中一个 串接在另一个串的末尾,生成一个新串。 如给出两个串s1和s2,把s2连接到s1之后, 生成一个新串s。
1. 串连接
例如,有两个串分别为s1 = ″Good ″, s2 = ″morning!″,则调用函数connect(s1, s2) 后,生成一个新串s = ″Good morning!″
4.2 串的存储结构
4.2.1 串的静态存储结构
串的静态存储结构采用顺序存储结构,简称为顺 序串。在计算机中,一个字符只占一个字节,所以串 中的字符是顺序存放在相邻字节中的。 串的顺序存储可用一个字符型数组和一个整型变 量来表示,其中字符型数组存放串值,整型变量存放 串的长度。
4.2 串的存储结构
4.2.2 串的链式存储结构
串的链式存储结构也称为链串,结构与链表类似,链串 中每个结点有两个域,一个是值域(data),用于存放字符 串中的字符,另一个是指针域(next),用于存放后继结点 的地址。 一个链串一般是由头指针唯一确定的。
优点:插入、删除运算很方便。
4.2 串的存储结构
存储密度 = 串值所占的存储位 / 实际分配的存储位 为了提高存储密度,可让每个结点的值域存放多个字符。 这种结构也叫做大结点结构。 如串s = “good morning!”的存储结构如下图所示。
第四章 串
– 例如
• 主串S = • 子串T = CD • 则index(S,T),返回子串T在S中,第一次出现的位置3
19
串的模式匹配
Brute-Force算法基本思想: • 从目标串s 的第一个字符起和模式串t的第一个字符进行比较 • 若相等,则继续逐个比较后续字符,否则从串s 的第二个字 符起再重新和串t进行比较。 • 依此类推,直至串t 中的每个字符依次和串s的一个连续的字 符序列相等,则称模式匹配成功,此时串t的第一个字符在串s 中的位置就是t 在s中的位置,否则模式匹配不成功。
两式联立可得:“T0…Tk-1”= “Tj-k…Tj-1”
注意:j为当前已知的失配位置,我们的目标是计算新起点k。式中仅剩 一个未知数k,理论上已可解!
奇妙的结果:k仅与模式串T有关!
27
新起点k怎么求?
根据模式串T的规律:“T0…Tk-1”=“Tj-k …Tj-1” 由当前失配位置j(已知),归纳计算新起点k的表达式。
j=next[j]的位置(即模式串继续向右移动),再比较 si 和 tj 。
依次类推,直到下列两种情况之一: 1)j退回到某个j=next[j]时有 si = tj,则指针各增1,继续匹配; 2)j退回至j=0,此时令指针各增1,即下一次比较 si+1和 t0 。
30
串的模式匹配:KMP算法
• 模式串的next函数
6
串的基本概念
4.两个字符串相等的充分必要条件为两个字符串的长度相等,并 且对应位置上的字符相等。
例如:‘abcd’ ≠ ‘bacd’ ‘abcd’ = ‘abcd’
7
串的基本操作
1.给串变量赋值 ASSIGN(S1,S2)
数据结构第四章串
(2) 置换操作:用联接算法来实现。用在求子串序号(a,b,h)中得到的 ind 将a分成3部分:第一部分是b在a中的第一个位置前的子串substr (a,1,ind-1);第二部分是b(以c来代替);第三部分是b在a中的最后一个 位置后的子串substr(a,ind+m,n)。 即 a substr(a,I,ind-1)||c||substr(a,ind+m,n)
4. 2 串的基本运算
对于串的基本操作,许多高级语言均提供了相应的运算或标准 库函数来实现。下面仅介绍几种常用的串运算。 (1)联接(concatenation) 联接是串的最基本,最重要的运算。两个串的联接是将一个串 紧接着放在另一个串的末尾。联接用符号“||”表示。 例如:a=”bei” b=“jing” a || b=“beijing” (2)求子串(substr) SUBSTR(a,m,n)功能: 从a 中截取子串,从第m个字符到第n个 字符的子串(m<n)。子串应是将串a中取出从标号m开始的连续n -m+1个字符。 例:SUBSTR(“ABCDEFG”,2,3)=”BC” 利用求子串及联接两种运算可以完成对串的插入、删除和修改。 例如: a=“bejing” b=“iy” ,将b插入到a的第二个字符之后 得到新的串s,则 s=substr(a,1,2) || b || substr(a,3,6) =“beiyjing”
(5)置换(repleace) 置换运算repleace(a,b,c)表示在a中搜索b,若b是a的 子串,就以c代替b,若不是,则经置换后,a不变。 例如:a=“monday”, b=“mon”, c=“thurs” repleace(a,b,c)=“thursday” 置换运算是将串a中所有的子串b用c来代替。 在一部分程序设计语言中没有实现,仍可用前三种运 算来完成。 置换算法过程:实现置换运算repleace(a,b,c),同 样也是在a中搜索是否与b相同的子串,若有,以c来代 替,再继续向下搜,直到在a中找不到和b相同的子串 为止。
数据结构第四章:串
例2、串的定位 、串的定位index(s,t,pos)
在主串s中取从第 个字符起、 相等的子串和T比较 在主串 中取从第pos个字符起、长度和串 相等的子串和 比较,若 中取从第 个字符起 长度和串T相等的子串和 比较, 相等,则求得函数值为i,否则值增1直至 中不存在和串T相等的子串 直至S中不存在和串 相等,则求得函数值为 ,否则值增 直至 中不存在和串 相等的子串 为止。 为止。
}
4.2 串的表示和实现
首先强调:串与线性表的运算有所不同,是以“串的整体” 首先强调:串与线性表的运算有所不同,是以“串的整体”作 为操作对象,例如查找某子串, 为操作对象,例如查找某子串,在主串某位置上插入一个子串 等。 串有三种机内表示方法: 串有三种机内表示方法:
定长顺序存储表示
顺序 存储 ——用一组地址连续的存储单元存储串值的字 用一组地址连续的存储单元存储串值的字 符序列, 静态存储方式 方式。 符序列,属静态存储方式。
4.1 串类型的定义 4.2 串的表示和实现
4.1 串的类型定义
4.1.1串的定义
定义:串(string)是由零个或多个任意字符组成的字 符序列,是数据元素为单个字符的特殊线性表。 的特殊线性表。 是数据元素为单个字符的特殊线性表 记为:an”
(n≥0 )
第4章 串(String) 章 )
本章主题:串的各种基本运算及其实现 本章主题: 教学目的:了解数据结构的基本概念, 教学目的:了解数据结构的基本概念,理解常用术语 教学重点: 教学重点: 掌握串的基本概念及其基本运算 掌握串的存储结构 主要内容: 主要内容: 1.串的基本概念 2.串的存储结构 2.串的存储结构 3.串的基本运算及其实现 3.串的基本运算及其实现
串其中0<=pos<=strlen(s)-1,且数组 且数组sub至少可容纳 至少可容纳len+1个字符。*/ 个字符。 串其中 且数组 至少可容纳 个字符
数据结构-第四章串
数据结构-第四章串串也叫字符串,它是由零个或多个字符组成的字符序列。
基本内容1 串的有关概念串的基本操作2 串的定长顺序存储结构,堆分配存储结构;3 串的基本操作算法;4 串的模式匹配算法;5 串操作的应⽤。
学习要点1 了解串的基本操作,了解利⽤这些基本操作实现串的其它操作的⽅法;2 掌握在串的堆分配存储结构下,串的基本操作算法;3 掌握串的模式匹配算法;第四章串 4.1 串的基本概念4.2 串存储和实现4.3 串的匹配算法4.4 串操作应⽤举例第四章串 4.1 串的基本概念 4.2 串存储和实现 4.3 串的匹配算法 4.4 串操作应⽤举例第四章串4.1 串的基本概念 4.2 串存储和实现 4.3 串的匹配算法 4.4 串操作应⽤举例4. 1 串类型的定义⼀、串的定义1 什么是串串是⼀种特殊的线性表,它是由零个或多个字符组成的有,a2, a3, ... a n’限序列,⼀般记作s = ‘a1其中 s----串名, a1,a2, a3, ... a n----串值串的应⽤⾮常⼴泛,许多⾼级语⾔中都把串作为基本数据类型。
在事务处理程序中,顾客的姓名、地址;货物的名称、产地。
可作为字符串处理,⽂本⽂件中的每⼀⾏字符等也可作为字符串处理。
下⾯是⼀些串的例⼦:(1)a = ‘ LIMING’(2)b = ‘NANJING UNIVERSITY OF SCIENCE &TECHNOLOGY’(3)c = ‘ DATA STRUCTURE’(4)d = ‘’说明:1) 串中包含的字符个数,称为串的长度。
长度为0的串称为空串,它不包括任何字符,上⾯(4)中的串d 是空串,(5)中的e 是包含⼀个空格符的空格串;2)串中所包含的字符可以是字母、数字或其他字符,这依赖于具体计算机所允许的字符集。
2 串的有关术语1)⼦串串中任意连续的字符组成的⼦序列称为该串的⼦串例:c = ‘ DATA STRUCTURE’,f=‘DATA’ f是c的⼦串2)⼦串的位置⼦串T 在主串S中的位置是指主串S中第⼀个与T相同的⼦串的⾸字母在主串中的位置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2、串的抽象数据类型定义
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) 初始条件:chars是字符串常量。 操作结果:生成一个其值等于chars的串T。
2.求子串SubString(&Sub,S,pos,len)
初始条件:串S存在, 1≤pos≤StrLength(S)
且 0≤len≤StrLength(S)-pos+1 。 操作结果:用Sub返回串S的第pos个字
符起长度为len的子串。 算法思想:求子串的过程即为复制字符
序列的过程,将串S中从第pos个字符 开始长度为len的字符序列复制到串 Sub中。
基本运算实现
1.串联接Concat(&T,S1,S2)
S1[0]
S2[0]
S1
S2
T
T[0]
MAXSTRLEN
( a ) S1[0]+S2[0]≤MAXSTRLEN
S1[0]
S1
S2[0]
S2
T
S2中被截去的部分
T[0]
MAXSTRLEN
( b ) S1[0]<MAXSTRLEN 而S1[0] +S2[0]>MAXSTRLEN
若S=T,则返回值=0;若S<T,则返回值<0
int comparestr(SString S,SString T) {
int i; for (i=1;i<=s[0]&&i<=t[0];i++)
if(s[i]!=t[i]) return (s[i]-t[i]); return (s[0]-t[0]); }
子串,串中任意个连续的字符组成的子序列称为该 串的子串。
主串,包含子串的串。
位置,字符在序列中的序号为该字符在串中的位置.
例:4个串
a='BEI',b='JING', c='BEIJING',d='BEI JING'
两个串相等,当且仅当这两个串的值相等.
空格串 (blank string,请注意此处不是空串), 由一个或多个空格组成的串''.
StrCompare(S,T) 初始条件:串S和串T存在。 操作结果:若S>T,则返回值>0;若S=T,则返回值=0; 若S<T,则返回值<0。
StrLength(S) 初始条件:串S存在。 操作结果:返回值S的元素个数,称为串的长度。
Concat(&T,S1,S2) 初始条件:串S1和S2存在。 操作结果:用T返回S1和S2联接成的新串。
4.2.1 定长顺序存储表示
思想: 用一组地址连续的存储单元存储串值的字 符序列
#define MAXSTRLEN 255//用户可在255以内定义最大串
长
typedef unsigned char SString[MAXSTRLEN+1]; //0号单元存放串的长度 串的实际长度可在这预定义长度的范围内随意, 超过预定义长度的串值则被舍去,称为“截断”。
第4章 串
4.1 串类型的定义 4.2 串的表示和实现 4.3 模式匹配算法 4.4 串操作应用举例
4.1 串类型的定义
1、名词术语
串(String)(或字符串),是由零个或多个字符组成 的有限序列。一般记做s=‘a1a2…an’(n>=0)
串的长度,串中字符的数目n。
空串(Null string),零个字符的串,它的长度为零。
SubString(&Sub,S,pos,len) 初始条件:串S存在,1≤pos≤StrLength(S)且0≤ len ≤StrLength(S)-pos+1 。 操作结果:用Sub返回串S的第pos个字符起长度为 len的子串。
……
} ADT String
4.2 串的表示和实现
4.2.1 定长顺序存储表示 4.2.2 堆分配存储表示 4.2.3 块链存储表示
算法实现
Status SubString(SString &Sub,SString S,int pos,int len)
{ 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; }
定长顺序存储结构总结
1.采用此存储结构,实现串操作的原操作 为“字符序列的复制”;操作的时间复 杂度基于复制的字符序列的长度
2.如果在操作中出现串值序列的长度超过 上界MAXSTRLEN时,约定用截尾法处理. 克服这点惟有不限定串的最大长度,即动 态分配串值的存储空间
思考练习:比较二个串,若S>T,则返回值>0;
4.2.2 堆分配存储表示
思想: 仍用一组地址连续的存储单元存储串值的字符序 列,但它们的存储空间是在程序执行过程中动态分配而 得。串的存储空间仍由malloc()函数来分配。 类型定义:
typedef struct{ char *ch; int length;
}HString;
S1[0]
S2[0]
S1
S2
T
S2串全部被截去
T[0]
MAXSTRLEN
( c ) S1[0]=MAXSTRLEN
算法实现
Status Concat(SString &T,SString S1,SString S2){ if (S1[0]+S2[0]<=MAXSTRLEN){ // 未截断
T[1..S1[0]]=S1[1..S1[0]]; T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]]; T[0]=S1[0]+S2[0]; uncut =TRUE;} else if(S1[0]<MAXSTRLEN){ // 截断 T[1..S1[0]]=S1[1..S1[0]]; T[S1[0]+1..MAXSTRLEN]=S2[1..MAXSTRLEN-S1[0]]; T[0]= MAXSTRLEN; uncut =FALSE;} else{ // 截断(仅取S1) T[0 ..MAXSTRLEN]= S1[0 ..MAXSTRLEN]; uncut =FALSE;} return uncut;}