目录

1  串的基本概念

2 串的存储实现

定长顺序串

定长顺序串的概念

定长顺序串基本操作的实现

串的简单模式匹配Brute-Force(布鲁特-福斯)算法

堆串

串的定义

堆串的基本操作

块链串

3  串的应用举例:简单的行编辑器

4 总结与提高

知识点

典型题例


计算机处理的对象分为数值处理和非数值处理,字符串是最基本的非数值数据。

字符串处理在语言编译、信息检索、文字编辑等领域有着广泛的应用。

1  串的基本概念

串(String)是零个或多个字符组成的有限序列。 一般记为: S=‘a1a2…an’ (n≥0)

子串:串中任意个连续的字符组成的子序列称为该串的子串。

主串:包含子串的串相应地称为主串。

空串: n=0时的串为空串

通常将字符在串中的序号称为该字符在串中的位置。

空格串:由一个或多个称为空格的特殊字符组成的串。

串相等:当且仅当两个串的值相等时,称这两个串是相等的


串的抽象数据类型定义:

ADT String {

数据对象:D={ai| ai ∈CharacterSet,i=1,2,…,n;  n≥0}

数据关系:R={<ai-1,ai>| ai-1,ai ∈D,i=2,…,n;  n≥0}

基本操作:

(1) StrAsign(S,chars)

初始条件:chars是字符串常量

操作结果:生成一个值等于chars的串S

(2) StrInsert(S,pos,T)

初始条件:串S和T存在,1≤pos≤StrLength(S) +1

操作结果:在串S的第pos个字符之前插入串T

(3) StrDelete(S,pos,len)

初始条件: 串S存在,1≤pos≤StrLength(S) -len +1

操作结果: 从串S中删除第pos个字符起长度为len的子串

(4) StrCopy(S,T)

初始条件: 串S存在

操作结果:由串T复制得串S

(5) StrEmpty(S)

初始条件: 串S存在

操作结果:若串S为空串,则返回TRUE,否则返回FALSE

(6)StrCompare(S,T)

初始条件: 串S和T存在

操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T, 则返回值<0

(7)StrLength(S)

初始条件: 串S存在

操作结果:返回串S的长度,即串S中的元素个数

(8)StrClear(S)

初始条件: 串S存在

操作结果:将S清为空串

(9)StrCat(S,T)

初始条件: 串S和T存在

操作结果:将串T的值连接在串S的后面

(10)SubString(Sub,S,pos,len)

初始条件:串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)

操作结果:若串S中存在与串T相同的子串,则返回它在串S中第pos个字符之后第一次出现的位置;否则返回0

(12)StrReplace(S,T,V)

初始条件: 串S,T和V存在, 且T是非空串

操作结果:用V替换串S中出现的所有与T相等的不重叠子串

(13)StrDestroy(S)

初始条件: 串S存在

操作结果:销毁串S


2 串的存储实现

定长顺序串

1定长顺序串的概念

定长顺序串是将串设计成一种静态结构类型,串的存储分配是在编译时完成的。

定长顺序串存储结构

#define MAXLEN 20
typedef struct {   /*串结构定义*/char ch[MAXLEN];int len;
} SString;

2.定长顺序串基本操作的实现

(1)串插入函数

有三种情况:

(1) 插入后串长(LA+LC+LB)≤MAXLEN,则将B后移LC个元素位置,再将C插入。

(2) 插入后串长>MAXLEN且pos+LC<MAXLEN,则B后移时会有部分字符被舍弃。

(3) 插入后串长>MAXLEN且pos+LC>MAXLEN,则 B的全部字符被舍弃(不需后移),并且        C在插入时也有部分字符被舍弃。


顺序串插入函数算法

StrInsert(SString *s, int pos, SString t)
/*在串s中下标为pos的字符之前插入串t */
{ int i;
if (pos<0 || pos>s->len) return(0); /*插入位置不合法*/
if (s->len + t.len<=MAXLEN) {   /*插入后串长≤MAXLEN*/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;}
else if (pos+t.len<=MAXLEN) {/*插入后串长>MAXLEN,但串t的字符序列可以全部插入*/for (i=MAXLEN-1;i>t.len+pos-1;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=MAXLEN;}
else {  /*插入后串长>MAXLEN,并且串t的部分字符也要舍弃for (i=0;i<MAXLEN-pos;i++) s->ch[i+pos]=t.ch[i];s->len=MAXLEN;}
return(1);
}

(2)串删除函数

StrDelete(SString *s, int pos, int len)
/*在串s中删除从下标pos起len个字符*/
{ int i;
if (pos<0 || pos>(s->len-len)) return(0);   /*删除参数不合法*/
for (i=pos+len;i<s->len;i++)s->ch[i-len]=s->ch[i]; /*从pos+len开始至串尾依次向前移动,实现删除len个字符*/s->len=s->len - len; /*s串长减len*/
return(1);
}

(3)串复制函数

StrCopy(SString *s, SString t)
/*将串t的值复制到串s中*/
{ int i;
for (i=0;i<t.len;i++) s->ch[i]=t.ch[i];
s->len=t.len;
}

(4)判空函数

StrEmpty(SString s)
/*若串s为空则返回1,否则返回0 */
{
if (s.len==0) return(1);
else return(0);
}

(5)串比较函数

StrCompare(SString s, SString t)
/*若串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]);
return(s.len - t.len);
}

(6)求串长函数

StrLength(SString s)
/* 返回串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的全部字符被舍弃(不需连接)。

串连接函数算法

StrCat(SString *s, SString t)
/*将串连接在串s的后面*/
{ int i, flag;
if (s->len + t.len<=MAXLEN)  /*连接后串长小于MAXLEN*/{
for (i=s->len; i<s->len + t.len; i++)s->ch[i]=t.ch[i-s->len];
s->len+=t.len;
flag=1;}
else if (s->len<MAXLEN)  /*连接后串长大于MAXLEN,但串s的长度小于MAXLEN,{                     即连接后串t的部分字符序列被舍弃*/
for (i=s->len;i<MAXLEN;i++)s->ch[i]=t.ch[i-s->len];
s->len=MAXLEN;
flag=0;}
else flag=0;  /* 串s的长度等于MAXLEN ,串t不被连接*/
return(flag);
}

(9)求子串函数

SubString(SString *sub, SString s, int pos, int len)
/*将串s中下标pos起len个字符复制到sub中*/
{ int i;
if (pos<0 || pos>s.len || len<1 || len>s.len-pos)
{ sub->len=0;
return(0);
}
else {
for (i=0; i<len; i++)
sub->ch[i]=s.ch[i+pos];
sub->len=len;
return(1);}
}

(10)定位函数

【问题分析】

T为目标串(主串),S为模式串(子串),在主串T中找子串S的过程为模式匹配(pattern matching)。用定位函数实现求子串T在主串S中从pos的位置开始第一次出现的位置序号,定位函数也叫串的模式匹配。

3. 串的简单模式匹配Brute-Force(布鲁特-福斯)算法

【算法思想】

简单的模式匹配算法是一种带回溯的匹配算法,算法的基本思想是:从主串S的第pos个字符开始,和模式串T的第一个字符开始比较,如果相等,就继续比较后续字符,如果不等,则从(回溯到)主串S的第pos+1个字符开始重新和模式串T比较,直到模式串T中的每一个字符和主串S中的一个连续字符子序列全部相等,则称匹配成功,返回和T中第一个字符相等的字符在主串T中的位置;或者主串中没有和模式串相等的字符序列,则称匹配不成功。

【算法描述】

实现时设i、j、start三个指示器:

i——指向主串T中当前比较的字符,起始指向T的首字符,此后,每比较一步,后移一步,一趟匹配失败时,回溯到该趟比较起点的下一位置。

j——指向子串S中当前比较的字符,起始指向S的首字符,此后,每比较一步,后移一步,一趟匹配失败时,回溯到S的首字符处。

start——记录每趟比较时在主串T中的起点,每趟比较后,后移一步,以便确定下一趟的起始位置。

顺序串的简单模式匹配(定位)函数算法

StrIndex(SString s,int pos, SString t)
/*求从主串s的下标pos起,串t第一次出现的位置,成功返回位置序号,不成功返回-1*/
{ int i, j, start;
if (t.len==0)  return(0);   /* 模式串为空串时,是任意串的匹配串 */
start=pos;  i=start;  j=0;  /* 主串从pos开始,模式串从头(0)开始 */
while (i<s.len && j<t.len)if (s.ch[i]==t.ch[j]) {i++; j++;}   /* 当前对应字符相等时推进 */
else { start++;        /* 当前对应字符不等时回溯 */
i=start;  j=0;   /* 主串从start+1开始,模式串从头(0)开始*/
}
if (j>=t.len) return(start);    /* 匹配成功时,返回匹配起始位置 */
else return(-1);    /* 匹配不成功时,返回-1 */
}

堆串

堆串的定义

字符串包括串名与串值两部分,而串值采用堆串存储方法存储,串名用符号表存储。

堆串存储方法:仍以一组地址连续的存储单元存放串的字符序列,但它们的存储空间是在程序执行过程中动态分配的。系统将一个地址连续、容量很大的存储空间作为字符串的可用空间,每当建立一个新串时,系统就从这个空间中分配一个大小和字符串长度相同的空间存储新串的串值。

堆串存储表示:

在C语言中,已经有一个称为“堆”的自由存储空间,并可用函数malloc()和函数free()完成动态存储管理。因此,我们可以直接利用C语言中的“堆”来实现堆串。此时堆串可定义如下:

typedef  struct
{ char  * ch;int  len;} HString;

其中len域指示串的长度,ch域指示串的起始地址。

串名符号表:所有串名的存储映像构成一个符号表。借助此结构可以在串名和串值之间建立一个对应关系,称为串名的存储映像。

堆串的存储映象示例

a='a program',b='string ',c='process',free=23。


堆串的基本操作

(1) 堆串赋值函数

StrAssign(HString *s,char *tval) /*将字符常量tval的值赋给串s */
{ int len,i=0;if (s->ch!=NULL) free(s->ch);while (tval[i]!='\0') i++;len=i;if (len) {     s->ch=(char *)malloc(len);if (s->ch==NULL) return(0); for (i=0;i<len;i++) s->ch[i]=tval[i];} else s->ch=NULL; s->len=len;return(1);
}

(2) 堆串插入函数

StrInsert(HString *s,int pos,HString *t)/*在串s中下标为pos的字符之前插入串t */
{  int i;char *temp;if (pos<0 || pos>s->len || s->len==0) return(0);temp=(char *)malloc(s->len + t ->len);if (temp==NULL) return(0);for (i=0;i<pos;i++) temp[i]=s->ch[i];for (i=0;i<t ->len;i++) temp[i+pos]=t -> ch[i];for (i=pos;i<s->len;i++) temp[i + t.-> len]=s->ch[i];s->len+=t -> len; free(s->ch);s->ch=temp;return(1);
}

(3) 堆串删除函数

StrDelete(HString *s,int pos,int len)
/*在串s中删除从下标pos起len个字符 */
{  int i; char *temp;if (pos<0 || pos>(s->len - len)) return(0);temp=(char *)malloc(s->len - len);if (temp==NULL) return(0);for (i=0;i<pos;i++) temp[i]=s->ch[i];for (i=pos;i<s->len - len;i++) temp[i]=s->ch[i+len];s->len=s->len-len; free(s->ch);s->ch=temp;return(1);
}

块链串

块链结构的定义

#define  BLOCK_SIZE  4       /*每结点存放字符个数*/
typedef struct Block{char   ch[BLOCK_SIZE];struct Block   *next;
} Block;typedef struct {Block   *head;Block   *tail;int     length;
} BLString;

3  串的应用举例:简单的行编辑器

文本编辑程序用于源程序的输入和修改,公文书信、报刊和书籍的编辑排版等。常用的文本编辑程序有Edit,WPS,Word等 。

为了编辑方便,可以用分页符和换行符将文本分为若干页,每页有若干行。我们把文本当作一个字符串,称为文本串,页是文本串的子串,行是页的子串。 我们采用堆存储结构来存储文本,同时设立页指针、行指针和字符指针,分别指向当前操作的页、行和字符,同时建立页表和行表存储每一页、每一行的起始位置和长度。

假设有如下Pascal源程序:

FUNC max(x,y:integer):integer;
VAR z:integer;
BEGINIF x>y THEN z:=x;ELSE z:=y;RETURN(z);END;


4 总结与提高

知识点

>>   字符串是一种特定的线性表,其特殊性就在于组成线性表的每个元素就是一个单字符。

>>   字符串常用的存储方式有三种:顺序串、堆串和块链串。

>>   顺序串以一维数组作为存储结构,运算实现类同顺序表。块链串以链表作为存储结构,运算实现类同链表。

>>   串的模式匹配算法是本章的重点,简单的模式匹配算法处理思路简单,由于进行了带回溯的处理,时间复杂度较高。改进的KMP模式匹配算法计算滑动位置,因而失配后无回溯,匹配速度较高。

典型题例

要求编写一个用带头结点的单链表实现串的模式匹配算法,每个结点存放一个字符(结点大小为1)。

【问题分析】

该算法类同顺序串的简单模式匹配,实现匹配过程需考虑链表的特征(从头比较的技术,指针保留的技术)。

【算法思想】

从主串s的第一个字符和模式串t的第一个字符开始比较,如果相等,就继续比较后续字符,如果不等,则从主串s的下一个字符开始重新和模式串t比较。一直到模式串t中的每一个字符依次和主串s中的对应字符相等,则匹配成功,返回主串的当前起始位置指针。如果主串中没有和模式串相同的子串,则称匹配不成功,返回空指针NULL。

【算法描述】

【学数据结构】-----串(顺序串、堆串、块链串)(7000字总结+代码+图)相关推荐

  1. 从零开始学数据结构和算法(二)线性表的链式存储结构

    链表 链式存储结构 定义 线性表的链式存储结构的特点是用一组任意的存储单元的存储线性表的数据元素,这组存储单元是可以连续的,也可以是不连续的. 种类 结构图 单链表 应用:MessageQueue 插 ...

  2. 数据结构小作业——串连接(块链结构)

    文章目录 概要 reference 串 存储结构 创建块链 连接块链 总 概要 以块链结构表示串,试编写将串s插入到串t某个字符之后的算法. reference link 串 和线性表相比就是对主要是 ...

  3. 0627-c-数据结构-块链串实现代码

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define linkNum 3//全局设置链表中 ...

  4. 严蔚敏数据结构C语言版——线性表的链式存储方式详细代码

    一.严蔚敏数据结构C语言版 由于书上的许多地方都是伪代码,所以下面的代码对课本上的做了一些改动,使代码能够正常运行 链表的定义即相关类型定义 typedef int ElementType; type ...

  5. 4-3-串的块链存储结构-串-第4章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第4章  串 - 块链串 --<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集 ...

  6. 串的块链存储c语言栈,小蚂蚁学习数据结构(18)——串的块链的代码实现

    感觉上块链的代码实现比数组的代码实现要难一些,估计因为数组的实现书上有伪代码,而块链连伪代码都木有,不过归根到底还是水平不行--哭瞎--╥﹏╥... /* 数据结构C语言版 串的块链存储表示和实现 * ...

  7. 迪杰斯特拉最全详解(朴素版,堆优化+邻接表存图/链式前向星存图)

    迪杰斯特拉 迪杰斯特拉算法分析 迪杰斯特拉(朴素版) 迪杰斯特拉堆优化(邻接表存图) 迪杰斯特拉堆优化(链式前向星存图) 最短路--spfa(链式前向星存图) 迪杰斯特拉算法分析 一般用三种数据结构存 ...

  8. 基于容器技术的阿里云区块链优势和实现方法

    摘要: 在2017年北京云栖大会的"开发者服务专场"上,阿里云高级技术专家余珊带来了<敏捷智连--基于容器技术的区块链业务创新>的精彩分享.分享中,他重点从阿里云容器服 ...

  9. 以串结构存储c语言版,数据结构C语言版 串的块链存储表示和实现

    <数据结构C语言版 串的块链存储表示和实现>由会员分享,可在线阅读,更多相关<数据结构C语言版 串的块链存储表示和实现(13页珍藏版)>请在人人文库网上搜索. 1.*数据结构C ...

  10. 【数据结构基础】-串-顺序结构的基本操作实现

    2019.10.12 数据结构中串的基本操作实现,包括串的定义,串的初始化,赋值,获取串的长度,串的比较,连接串,求子串,清空串. 语言:c语言 运行环境:dev #include <stdio ...

最新文章

  1. ubuntu-make/makefile/cmake
  2. nagios搭建与配置
  3. python 中的接口_python中接口
  4. Android源码学习之工厂方法模式应用
  5. 数据港:攻破OPEX+SLA难题,实现全生命周期效能管理
  6. one order event handling - event filtering
  7. sqlserver2008r2修改表不能保存的解决方法
  8. 使用优化的基于模糊规则的特征选择技术和基于树的集成方法进行山洪敏感性建模--文献阅读
  9. 基于mysql和php的分布式事务处理1,基于MySQL和PHP的分布式事务处理
  10. python制作简单K线图
  11. php class variable,解决关于PHP“Undefined variable”变量未定义
  12. 小象电商是采用JAVA开发的B2B2C多用户商城系统。
  13. sed-awk命令详解
  14. linux之stat
  15. 使用Gitbook来编写你的Api文档
  16. 一个Lua脚本的解密过程
  17. Python 正则表达模块详解
  18. 机械制图标准化基础知识简介
  19. 如何删除重复项只保留最新项
  20. 网易2018校园招聘编程题真题集合

热门文章

  1. Baby Sign Language
  2. 近几十年基础科学的停滞影响研究
  3. 海洋角度分析全球气候变暖停滞原因
  4. 新西兰 计算机 转专业,想去新西兰留学读硕士,但又想转专业
  5. 关于学习Android的三个终极问题
  6. 一篇文章入门Python
  7. 抽取MySQL数据成文件_MySql导入和抽取大数量级文件数据
  8. 自用机器学习笔记(1):什么是概率以及似然
  9. 北京大学历届学生名单 计算机,北京大学历史系历届学生名单
  10. nvidia卸载程序无法继续运行_win10系统下nvidia安装程序无法继续不兼容的解决办法_nvidia显卡驱动与系统不兼容...