数据结构 串结构
数据结构第四章 串

数据结构第四章串在数据结构的世界里,串是一种非常基础且重要的结构。
它看似简单,却在很多实际的程序设计和应用中发挥着关键作用。
串,简单来说,就是由零个或多个字符组成的有限序列。
这就好比我们日常生活中的一句话、一段文字或者一个密码。
从存储方式上来看,串可以采用顺序存储和链式存储两种方式。
顺序存储就像是把一串珠子穿在一根线上,珠子依次排列,位置固定。
在计算机中,我们可以用一个连续的数组来存储串中的字符。
这种方式简单直观,访问速度快,但存在着一些局限性。
比如说,如果我们事先不知道串的长度,可能会造成存储空间的浪费或者不足。
相比之下,链式存储则更加灵活。
它就像把珠子用链条串起来,每个珠子(也就是字符)都有一个指针指向下一个珠子。
这样,即使在插入或删除字符时,也不需要像顺序存储那样进行大量的数据移动。
但是,链式存储的缺点是访问速度相对较慢,因为需要通过指针依次查找。
接下来,让我们看看串的一些基本操作。
串的比较是经常会用到的操作。
比较两个串的大小,不能像比较数字那样简单地直接比较,而是要从串的第一个字符开始,逐个字符进行比较。
如果在某个位置上的字符不同,那么 ASCII 码值大的那个串就更大;如果前面的字符都相同,但是一个串先结束了,那么长度短的串就更小。
串的连接也是常见的操作。
想象一下把两段绳子接在一起,就形成了一个更长的绳子。
串的连接也是类似的道理,把两个串首尾相连,形成一个新的串。
但在实际操作中,要注意存储空间的分配,确保有足够的空间来容纳连接后的串。
还有串的子串操作。
比如说,从一篇文章中截取一段文字,这就是获取一个子串。
在程序中,我们需要明确指定子串的起始位置和长度,才能准确地获取到所需的部分。
串的模式匹配更是一个重要的应用。
这就像是在一篇长篇小说中寻找特定的关键词或者短语。
最常见的模式匹配算法有朴素模式匹配算法和 KMP 算法。
朴素模式匹配算法比较直接,就是从主串的开头逐个字符与模式串进行匹配。
而 KMP 算法则通过对模式串进行预处理,利用已经匹配的部分信息,减少不必要的比较,从而提高匹配的效率。
数据结构-4 串

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

第五章串§5.1串的定义串:又称字符串。
通常把串看作一种数据结构,它是数据元素仅由单个字符组成的特殊线性表。
一般说来,串是零个或有限个字符的线形序列。
记作:s='a1 a2… a n' n≥0其中:s:是串名,用单引号括起来的字符序列为串的值。
a i:为串的元素,它可以是字母、数字或其他字符(运算符、分割符、汉字等)。
n:为串的长度(即串中字符的个数)。
n=0时,称为空串。
注意:单引号本身不属于串,只是为了避免和其它变量混淆。
例如:a='BEIJING'其值为字符序列BEIJING两个特殊的串:①空格串:空格串是仅由空格组成的串,记作s=' ',串中空格字符的个数即为其长度(>0),为了清楚起见,往往用符号φ来表示空格。
②空串:空串中无任何字符,记作s='',其长度为0。
按字符在字符串中的次序可以规定字符的大小。
§5.2 串的存储结构串作为一种特殊的线性表,线性表的顺序存储结构和链式存储结构对串都是适用的。
一、顺序存储在此种存储方式中,串的字符相继按存入连续的存储单元中,有三种格式:1.紧缩格式(在按字编址的机器中)是在一个存储单元中存放多个字符,假定一个存储单元可存放k个字符(字长为4),而给出的串长度为n 全都利用上。
2.非紧缩格式:不管机器字的长短,在一个字中只存放一个字符。
如下图所示:3.以字节为单位存储(在按字节编址的机器中)通常因为一个字节恰好存储一个字符的ASCII 码,这就自然形成了一个字节存放一个字符的单字节存储格式,既节省空间,又处理方便。
可见顺序分配的共性,空间利用率高,访问方便,但插入删除不方便,链表的存储恰恰弥补了这一不足。
二、链式存储第一个字中存放串长值 例如:设k=4,存储如图:10 1312 11 ┅当结点大小大于1时,一个串所占的结点中最后一个结点不一定全被串值占满这时,一般都补上非串值的字符“#”。
数据结构第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;
串-数据结构实验报告

串-数据结构实验报告串数据结构实验报告一、实验目的本次实验的主要目的是深入理解和掌握串这种数据结构的基本概念、存储方式以及相关的操作算法。
通过实际编程实现串的基本操作,提高对数据结构的理解和编程能力,培养解决实际问题的思维和方法。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理(一)串的定义串是由零个或多个字符组成的有限序列。
在本次实验中,我们主要关注的是字符串。
(二)串的存储方式1、顺序存储定长顺序存储:使用固定长度的数组来存储字符串,长度不足时用特定字符填充。
堆分配存储:根据字符串的实际长度动态分配存储空间。
2、链式存储每个节点存储一个字符,并通过指针链接起来。
(三)串的基本操作1、串的创建和初始化2、串的赋值3、串的连接4、串的比较5、求子串6、串的插入和删除四、实验内容及步骤(一)顺序存储方式下串的实现1、定义一个结构体来表示顺序存储的字符串,包含字符数组和字符串的实际长度。
```cppstruct SeqString {char str;int length;};```2、实现串的创建和初始化函数```cppSeqString createSeqString(const char initStr) {int len = strlen(initStr);SeqString s;sstr = new charlen + 1;strcpy(sstr, initStr);slength = len;return s;}```3、串的赋值函数```cppvoid assignSeqString(SeqString& s, const char newStr) {delete sstr;int len = strlen(newStr);sstr = new charlen + 1;strcpy(sstr, newStr);slength = len;}```4、串的连接函数```cppSeqString concatSeqString(const SeqString& s1, const SeqString& s2) {SeqString result;resultlength = s1length + s2length;resultstr = new charresultlength + 1;strcpy(resultstr, s1str);strcat(resultstr, s2str);return result;}```5、串的比较函数```cppint compareSeqString(const SeqString& s1, const SeqString& s2) {return strcmp(s1str, s2str);}```6、求子串函数```cppSeqString subSeqString(const SeqString& s, int start, int len) {SeqString sub;sublength = len;substr = new charlen + 1;strncpy(substr, sstr + start, len);substrlen ='\0';return sub;}```7、串的插入函数```cppvoid insertSeqString(SeqString& s, int pos, const SeqString& insertStr) {int newLength = slength + insertStrlength;char newStr = new charnewLength + 1;strncpy(newStr, sstr, pos);strcpy(newStr + pos, insertStrstr);strcpy(newStr + pos + insertStrlength, sstr + pos);delete sstr;sstr = newStr;slength = newLength;}```8、串的删除函数```cppvoid deleteSeqString(SeqString& s, int start, int len) {int newLength = slength len;char newStr = new charnewLength + 1;strncpy(newStr, sstr, start);strcpy(newStr + start, sstr + start + len);delete sstr;sstr = newStr;slength = newLength;}```(二)链式存储方式下串的实现1、定义一个节点结构体```cppstruct LinkNode {char data;LinkNode next;LinkNode(char c) : data(c), next(NULL) {}};```2、定义一个链式存储的字符串类```cppclass LinkString {private:LinkNode head;int length;public:LinkString(const char initStr);~LinkString();void assign(const char newStr);LinkString concat(const LinkString& other);int compare(const LinkString& other);LinkString subString(int start, int len);void insert(int pos, const LinkString& insertStr);void deleteSub(int start, int len);};```3、实现各个函数```cppLinkString::LinkString(const char initStr) {length = strlen(initStr);head = NULL;LinkNode p = NULL;for (int i = 0; i < length; i++){LinkNode newNode = new LinkNode(initStri);if (head == NULL) {head = newNode;p = head;} else {p>next = newNode;p = p>next;}}}LinkString::~LinkString(){LinkNode p = head;while (p) {LinkNode temp = p;p = p>next;delete temp;}}void LinkString::assign(const char newStr) {//先释放原有的链表LinkNode p = head;while (p) {LinkNode temp = p;p = p>next;delete temp;}length = strlen(newStr);head = NULL;p = NULL;for (int i = 0; i < length; i++){LinkNode newNode = new LinkNode(newStri);if (head == NULL) {head = newNode;p = head;} else {p>next = newNode;p = p>next;}}}LinkString LinkString::concat(const LinkString& other) {LinkString result;LinkNode p1 = head;LinkNode p2 = otherhead;LinkNode p = NULL;while (p1) {LinkNode newNode = new LinkNode(p1->data);if (resulthead == NULL) {resulthead = newNode;p = resulthead;} else {p>next = newNode;p = p>next;}p1 = p1->next;}while (p2) {LinkNode newNode = new LinkNode(p2->data);if (resulthead == NULL) {resulthead = newNode;p = resulthead;} else {p>next = newNode;p = p>next;}p2 = p2->next;}resultlength = length + otherlength;return result;}int LinkString::compare(const LinkString& other) {LinkNode p1 = head;LinkNode p2 = otherhead;while (p1 && p2 && p1->data == p2->data) {p1 = p1->next;p2 = p2->next;}if (p1 == NULL && p2 == NULL) {return 0;} else if (p1 == NULL) {return -1;} else if (p2 == NULL) {return 1;} else {return p1->data p2->data;}}LinkString LinkString::subString(int start, int len) {LinkString sub;LinkNode p = head;for (int i = 0; i < start; i++){p = p>next;}for (int i = 0; i < len; i++){LinkNode newNode = new LinkNode(p>data);if (subhead == NULL) {subhead = newNode;} else {LinkNode temp = subhead;while (temp>next) {temp = temp>next;}temp>next = newNode;}p = p>next;}sublength = len;return sub;}void LinkString::insert(int pos, const LinkString& insertStr) {LinkNode p = head;for (int i = 0; i < pos 1; i++){p = p>next;}LinkNode insertHead = insertStrhead;while (insertHead) {LinkNode newNode = new LinkNode(insertHead>data);newNode>next = p>next;p>next = newNode;p = p>next;insertHead = insertHead>next;}length += insertStrlength;}void LinkString::deleteSub(int start, int len) {LinkNode p = head;for (int i = 0; i < start 1; i++){p = p>next;}LinkNode temp = p>next;for (int i = 0; i < len; i++){LinkNode delNode = temp;temp = temp>next;delete delNode;}p>next = temp;length = len;}```(三)测试用例1、顺序存储方式的测试```cppint main(){SeqString s1 = createSeqString("Hello");SeqString s2 = createSeqString("World");SeqString s3 = concatSeqString(s1, s2);std::cout <<"连接后的字符串: "<< s3str << std::endl; int cmpResult = compareSeqString(s1, s2);if (cmpResult < 0) {std::cout <<"s1 小于 s2" << std::endl;} else if (cmpResult == 0) {std::cout <<"s1 等于 s2" << std::endl;} else {std::cout <<"s1 大于 s2" << std::endl;}SeqString sub = subSeqString(s1, 1, 3);std::cout <<"子串: "<< substr << std::endl; insertSeqString(s1, 2, s2);std::cout <<"插入后的字符串: "<< s1str << std::endl; deleteSeqString(s1, 3, 2);std::cout <<"删除后的字符串: "<< s1str << std::endl; return 0;}```2、链式存储方式的测试```cppint main(){LinkString ls1("Hello");LinkString ls2("World");LinkString ls3 = ls1concat(ls2);std::cout <<"连接后的字符串: ";LinkNode p = ls3head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;int cmpResult = ls1compare(ls2);if (cmpResult < 0) {std::cout <<"ls1 小于 ls2" << std::endl;} else if (cmpResult == 0) {std::cout <<"ls1 等于 ls2" << std::endl;} else {std::cout <<"ls1 大于 ls2" << std::endl;}LinkString sub = ls1subString(1, 3);std::cout <<"子串: ";p = subhead;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;ls1insert(2, ls2);std::cout <<"插入后的字符串: ";p = ls1head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;ls1deleteSub(3, 2);std::cout <<"删除后的字符串: ";p = ls1head;while (p) {std::cout << p>data;p = p>next;}std::cout << std::endl;return 0;}```五、实验结果及分析(一)顺序存储方式1、连接操作成功实现,输出了正确连接后的字符串。
数据结构(串)

数据结构(串)数据结构(串)1.介绍1.1 定义数据结构(串)是计算机科学中的一种基础数据结构,用于存储和操作一系列具有相同数据类型的元素的集合。
1.2 特性- 顺序存储:串中的元素按照在字符串中的顺序存储。
- 长度可变:可以动态改变串的长度。
- 计数方式:通常使用0开始计数。
1.3 应用字符串的数据结构广泛应用于文本处理、模式匹配、编译器设计等领域。
2.串的基本操作2.1 创建串:定义一个字符串变量并为其分配内存空间。
2.2 销毁串:释放字符串变量占用的内存空间。
2.3 清空串:将字符串中的元素清空,使字符串变为空串。
2.4 判断串是否为空:判断字符串是否为空串。
2.5 获取串的长度:获取字符串中元素的个数。
2.6 拷贝串:将一个串拷贝到另一个串中。
2.7 两个串:将两个串连接成一个新的串。
2.8 截取子串:从原串中截取一段子串。
2.9 查找子串:在串中查找指定子串的位置。
2.10 替换子串:在串中将指定子串替换成新的子串。
2.11 插入子串:在串中指定位置插入一个子串。
2.12 删除子串:从串中删除指定的子串。
3.串的存储结构3.1 顺序存储结构:使用一维数组存储字符串的字符元素。
3.2 链式存储结构:使用链表存储字符串的字符元素,每个节点存储一个字符。
4.串匹配算法4.1 暴力匹配算法:逐个比较字符串中的字符,若匹配失败则向后移动。
4.2 KMP算法:利用前缀函数预处理,避免重复比较已经匹配的字符。
4.3 Boyer-Moore算法:从匹配串的末尾开始比较,利用坏字符规则和好后缀规则跳过不必要的比较。
5.附件本文档不涉及附件。
6.法律名词及注释- 数据结构:指计算机科学中研究数据存储方式及其相关操作的学科。
- 串:也称为字符串,是由零个或多个字符组成的有序序列。
数据结构-4 串

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

数据结构
数据结构
串
相关术语 串的长度 空串 子串 主串 两个串相等
串的顺序存储结构
串的顺序存储结构用一组连续的存储单元(数组)依次存 储串中的字符序列,需要事先定义一个固定长度的存储区域 存储字符串(如数组)。
串的顺序存储结构
顺序串的基本操作
字符串的初始化 字符串的复制 字符串的连接 子串的提取 字符串的插入 字符串的删除 字符串的遍历
串的应用
文本编辑程序(如Windows中的notepad程序)是一个面向用 户的系统服务程序,应用于程序的修改和输入、书籍的编辑 排版等。利用计算机进行编辑工作,是将文本(一段程序、 一组数据、一篇文章等)。视为一个有限字符序列,然后可 以运用关于串的各种操作对文本进行诸如增、改、删除等操 作。
文本编辑器
简单的模式匹配算法(BF算法)
主要思想
蛮力算法,从主串的第一个字符开始和模式串的第一个字 符开始比较,若相等则继续比较后续字符;否则从主串s的 第二个字符开始重新与模式串t的第一个字符比较,按照这个 方式,继续下去。如果模式串t和主串s的某一段连续子串相 等,则匹配成功,并返回模式串t的第一个字符在主串中的位 置;若匹配不成功,则返回-1。
该算法主要消除了主串指针(i指针)的回溯,利用已经 得到的部分匹配结果将模式串右滑尽可能远的一段距离再 继续比较,从而使算法效率有某种程度的提高
KMP算法
KMP算法
KMP算法中,主串指针i不回溯,由模式串指针j退到某一个 位置k上,使模式串中的k之前的(k-1)个字符与主串中的i之 前的(k-1)个字符相等,这样可以减少匹配的次数,从而提 高效率。所以,KMP算法的关键在于如何找到k。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 定长顺序存储表示
顺序 存储 ——用一组地址连续的存储单元存储串值的字 符序列。
• 堆分配存储表示
——用一组地址连续的存储单元存储串值的字 符序列,但存储空间是在程序执行过程中动态 分配而得。
链式 • 串的块链存储表示 存储
——链式方式存储
1.定长顺序存储特点:
用一组连续的存储单元来存放串,直接使用定长的字符数 组来定义,数组的上界预先给出,故称为静态存储分配。 例如: #define Maxstrlen 255 //用户可用的最大串长 typedef unsigned char SString[ Maxstrlen+1 ]; SString s; //s是一个可容纳255个字符的顺序串。
…… Index(S, T, pos) Replace(&S, T,V)
// 返回子串T在pos之后的位置 // 用子串V替换子串T
}ADT Sting
练习: 设 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)= 14 4 ‗STUDENT‘ ‗O‘ 3 0 ( s中没有t!)
if (!(S.ch=(char*)realloc(S.ch, (S.length+T.length)*sizeof(char)) )) exit(OVERFLOW); for ( i=S.length-1; i>=pos-1; --i ) //为插入T而腾出pos之后的位置
S.ch[i+T.length] = S.ch[i];
5) 联接两个串成新串
Status Concat ( HString &T, Hstring S1, Hstring S2 ) { // 用T返回由S1和S2联接而成的新串。 if (T.ch) free(T.ch); // 释放旧空间 if ( !(T.ch = (char *) malloc ((S1.length+S2.length) * sizeof (char) ) ) ) exit ( OVERFLOW); T.ch[0 .. S1.length-1] = S1.ch[0 .. S1.length-1]; T.length = S1.length + S2.length ; T.ch[S1.length .. T.length-1] = S2.ch[0 .. S2.length-1]; return OK; } // Concat
子串位置: 子串的第一个字符的序号。 字符位置: 字符在串中的序号。 串相等: 串长度相等,且对应位置上字符相等。
0个或多个 字符组成的序列,一般记 练1:串是由 为 S=‘a1a2……an‘ 。
练2:现有以下4个字符串: a =‗BEI‘ b =‗JING‘ c = ‗BEIJING‘
d = ‗BEI JING‘
//从S的pos位置起全部字符均后移
S.ch[pos-1…pos+T.length-2] = T.ch[0…T.length-1];
//插入T,略/0
S.length + = T.length;
} return OK; }//StrInsert
//刷新S串长度
2) 堆分配存储表示
Status StrAssign( HString &T, char *chars ) { if (T.ch) free(T.ch);
Concat =concatenation,在字符串处理中,把多个短字符串合成为长字符 串的操作。
数据结构课程的内容
第4章 串(String)
1. 定义 2. 逻辑结构 3. 存储结构 4. 运算规则 5. 实现方式
4.1 4.2 4.3
串类型的定义 串的表示和实现 串的模式匹配算法
4.1
串类型的定义
串的抽象数据类型定义(参见教材P71) ADT Sting{ Objects: D={ai | ai∈CharacterSet, i=1, 2,…,n, n≥0} Relations: R1={<ai-1,ai> | ai-1,ai ∈D, i=2, …,n} functions: // 有13种之多 StrAssign(&T, chars) // 串赋值,生成值为chars的串T 最 StrCompare(S,T) // 串比较,若S>T,返回值大于0… 小 操 StrLength(S) // 求串长,即返回S的元素个数 作 Concat(&T, S1, S2) // 串连接,用T返回S1+S2的新串 子 SubString(&Sub, S, pos, len) // 求S中pos起长度为len的子串 集
串即字符串,是由零个或多个字符组成的有限序列,是数据 元素为单个字符的特殊线性表。 记为: s =‗ a1 , a2 , …….. , an‘ (n≥0 )
隐含结束符‘/0‘ , 串名 串值(用‘ ’ 括起来) 即ASCII码NULL 若干术语: 串长: 串中字符个数(n≥0). n=0 时称为空串 。 空白串: 由一个或多个空格符组成的串。 子串: 串s中任意个连续的字符序列叫s的子串; S叫主串。
特点: 若在操作中串值改变,还可以利用realloc函数按新 串长度增加(堆砌)空间。 约定:所有按堆存储的串,其关键信息放置在:
Typedef struct {
char *ch; // 若非空串,按串长分配空间; 否则 ch = NULL
int length; //串长度 }HString
1)用‚堆‛实现串插入操作(教材P75)
直到终值为“假” 停止,串尾特征 是‘/0‘= NULL=0
for (i=0, c=chars; c; ++i, ++c); else{
//求串长度
if (!i) {T.ch = NULL; T.length = 0;}
if (!(T.ch = (char*)malloc(i*sizeof(char)))) exit(OVERFLOW); T.ch[0..i-1] = chars[0..i-1]; T.length =i; } Return OK;
Status StrInsert ( HString &S, int pos, HString T ) {
//在串S的第pos个字符之前(包括尾部)插入串T
if (pos<1||pos>S.length+1) return ERROR; if(T.length){
//pos不合法则告警
//只要串T不空,就需要重新分配S空间,以便插入T
注: • 一般用SString[0]来存放串长信息; •C语言约定在串尾加结束符 ‘ \0‘,以利操作加速,但不计入串长; •若字符串超过Maxstrlen 则自动截断(因为静态数组存不 进去)。
实现方式:参见教材P73编程两例,两串连接和求子串
1) 串连接Concat(&T, S1,S2)
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] < MAXSTRSIZE ) // 截断 { T[ 1..S1[0] ] = S1[ 1..S1[0] ]; T[ S1[0] +1 .. MAXSTRLEN ] = S2[ 1.. MAXSTRLEN- S1[0]]; T[0] = MAXSTRLEN; uncut = FALSE; } else { T[ 0.. MAXSTRLEN ] = S1[ 0.. MAXSTRLEN ]; // 截取(仅取S1) uncut = FALSE; } return uncut; } // Concat
2) 求子串函数SubString (&Sub, S, pos, len)
将串S中从第pos个字符开始长度为len的字符序列复 制到串Sub中(注:串Sub的预留长度与S一样)
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; //pos不合法则警告 Sub[1……len] = S[pos……pos+len-1]; Sub[0]=len; return OK; }
指针变量C也可以自 增!意即每次后移一 个数据单元。
}//StrAssign
3) 比较字符串是否相同 Int Strcompare ( Hstring S, Hstring T ) { for ( i = 0; i < S.length && i <T.length; ++i ) if ( S.ch[i] != T.ch[i] ) return S.ch [i] – T.ch[i]; return S.length- T.length; } // StrCompare 4) 清空字符串 Status ClearString ( Hstring &S) { if ( S.ch ) { free(S.ch); S.ch = NULL; } S.length = 0; return OK; } // ClearString