串的基本概念
串(String)
是由零个或多个字符组成的有限序列。
记为
S= ‘a1a2…an’ (n≥0)
串的名字:串的标识符,如S。
串的值:有限字符序列,如’12345’ 。
串的长度:串中字符的个数。
空串和空格串
空串:是无任何字符组成的串。
空格串:由一个或多个空格组成的串。
如:一个空格串’ ’ 、多个空格的串’ '。
串相等
两个串的长度相等,且对应字符都相等。
子串和主串
子串:串中任意连续字符组成的子序列称为该串的子串。
主串:包含子串的串。
子串在主串的位置:以子串的第一个字符在主串中的位置来表示。
例如:
A=‘China Beijing’,B=‘Beijing’, C=‘China’,则B和C是A的子串,B在A中的位置是7,C在A中的位置是1。
因此:串是一种特定的线性表,其数据对象限定为字符集。
# 串的抽象数据类型定义
ADT String {
数据对象:限定为字符集
数据关系:线性关系
基本操作:赋值、插入串、删除子串、复制串、判空串、比较串、串长度、连接串、求子串、模式匹配、替换子串、销毁串。
} ADT String ;
串的存储实现
定长顺序串
串的存储实现方法主要有:定长顺序串、堆串、块链串。
定长顺序串存储结构
用一组连续的存储单元依次存储串中的各个字符。逻辑上相邻的字符,物理上也相邻。串的存储空间分配在编译时完成,不能更改。
定长顺序串类型定义
#define MAXLEN 40
typedef struct
{
char ch[MAXLEN]; /* 串的最大空间 */
int len; /* 串的长度 */
} SString; /*定长顺序串的类型 */
定长顺序串基本操作的实现
若串的实际长度超过定义的最大长度时,超过最大长度的串值则被舍去,称为(截断)。
串插入、串连接、串置换存在截断问题。
(1) 串插入 StrInsert(&s,pos,t)
插入后串长≤ MAXSIZE
插入后串长>MAXSIZE,串t可插入
插入后串长>MAXSIZE,串t部分舍弃
① 插入后串长≤ MAXSIZE
for(i=s->len+t.len-1;i>=t.len+pos;i--)
s->ch[i]=s->ch[i-t.len];
for(i=pos;i<t.len+pos;i++)
s->ch[i]=t.ch[i-pos];
s->len+=t.len;
② 插入后串长>MAXSIZE,串t可全部插入
for(i=MAXLEN-1;i>t.len+pos-1;i--)
s->ch[i]=s->ch[i-t.len];
for(i=pos;i<t.len+pos;i++)
s->ch[i]=t.ch[i-pos];
s->len=MAXLEN;
③ 插入后串长>MAXSIZE,串t部分舍弃
for(i=pos;i<MAXLEN;i++)
s->ch[i]=t.ch[i-pos];
s->len=MAXLEN;
(2) 串删除 StrDelete(&s,pos,len)
(3) 串复制 StrCopy(&s,t)
(4) 判空 StrEmpty(s)
(5) 串比较 StrCompare(s,t)
(6) 求串长 StrLength(s)
(7) 清空 StrClear(&s)
(8) 串连接 StrCat(&s,t)
(9) 求子串 SubString(&sub, s,pos,len)
(10) 定位 StrIndex(s,pos,t)
简单的模式匹配算法
即Brute-Force(布鲁特-福斯)算法
目标串即主串、模式串即子串
目标串S:ababcabcacbab
模式串T:abcac
堆串
堆
系统将一个地址连续、容量很大的存储空间作为可用空间,称为堆。
程序在运行过程中,可以在堆中申请一个地址连续的空间存储元素。
堆串:存储串值
程序在运行过程中,在堆中动态申请一个地址连续的空间存储一个字符串。
例如:在下面的堆中存储了3个堆串。
heap[MAXSIZE] free_index=23
串名
串名符号表:所有串名的存储映像构成一个符号表。借助此结构可以在串名和串值之间建立一个对应关系,称为串的存储映像。
字符串的组成
串名、串值
存储方法:
串值:堆串存储
串名:符号表存储
堆串的特点
既有顺序存储的特点,又有动态存储的特点。
C语言的堆
已有堆,可用malloc()和free()在堆中完成动态存储管理。
堆串类型的定义
typedef struct
{
char *ch; /* ch堆串的起始地址 */
int len; /* len堆串的串长 */
} HString; /* HString堆串的类型*/
堆串的操作
堆串的插入、连接、删除、赋值、置换等涉及空间大小的变化,则直接重新申请堆串空间,释放原堆串空间即可,不存在舍弃字符的问题。
堆串不涉及串长的操作同定长顺序串。
块链串
块链串
串的链式存储结构,每个结点可以存放若干字符,每个结点称为块,整个链表称为块链串。
存储密度=4/6=2/3
块及块链串类型的定义
#define BLOCK_SIZE 4 /* 结点大小*/
typedef struct Block {
char ch[BLOCK_SIZE]; /* 字符空间*/
struct Block *next; /* 指针域 */
} Block; /* 块类型*/
typedef struct {
Block *head; /* 串头指针*/
Block *tail; /* 串尾指针*/
int len; ; /* 串长*/
} BLString; /* 块链串类型 */
结点大小等于1的存储结构
typedef struct chBlock {
char ch; /* 一个字符*/
struct Block *next; /* 指针域 */
} Link; /* 块类型*/
typedef struct {
Link *head; /* 串头指针*/
Link *tail; /* 串尾指针*/
int len; ; /* 串长*/
} LKString; /* 块链串类型 */
串的应用举例简单的行编辑器
文本编辑
利用分页符和换行符把文本划分为若干页,每页有若干行。
可以把文本当作一个字符串,称为文本串,页就是文本串的子串,行又是页的子串。
存储结构
采用堆存储结构存储文本。
设立页指针、行指针、字符指针,分别指向当前操作页、行和字符。
建立页表:存储每一页的起始位置和长度。
建立行表:存储每一页的起始位置和长度。
操作
(1) 当在某行内编辑字符
修改行表中该行的长度,若空间超出,则需要重新分配空间,同时修改起始位置和长度。
(2) 插入或删除一行
进行行表的插入和删除,当行的插入和删除涉及业的变化时还要对页表进行修改。
总结
- 逻辑结构:串是一种特定的线性表,特定每个元素是一个单字符。
- 存储结构:定长顺序串、堆串、块链串。
- 存储及运算:定长顺序串以一维数组作为静态存储结构,运算实现同顺序表。堆串以动态分配的方式产生一组地址连续的存储单元以顺序方式存放串中的字符,运算实现同顺序表。块链串以链表作为存储结构,运算实现同链表。
- 串的模式匹配算法:BF算法、KMP算法
欢迎大家加我微信交流讨论(请备注csdn上添加)