概述
前几次我们介绍了栈和队列两种特殊的线性表,它们都是操作位置受限的线性表:限制了插入和删除操作发生的位置。
这次我们介绍另一种特殊的线性表,它虽然没有操作位置限制,但却有元素类型限制:它限制元素类型只能是字符,这样的线性表我们称之为串。
还是老规矩:
程序在码云上可以下载。
地址:https://git.oschina.net/601345138/DataStructureCLanguage.git
串可以进行很多操作,有很多有特色的操作是线性表中没有的,比如:串的模式匹配。
模式匹配算法分为BF和KMP算法两种,本次程序将基于实现的顺序串继续实现这两种模式匹配算法。
首先看看串的ADT定义:
ADT String {
数据对象:D ={ai | ai∈Characterset,(i=1,2,…,n, n≥0)}
数据关系:R1 = {<ai-1,ai>|ai-1,ai ∈ D,(i=2,3,…,n)}
基本操作:
StrAssign (&T, chars)
初始条件:chars 是字符串常量。
操作结果:把 chars 赋为T的值。
StrCopy (&T, S)
初始条件:串 S 存在。
操作结果:由串 S 复制得串T。
DestroyString (&S)
初始条件:串 S 存在。
操作结果:串 S 被销毁。
StrEmpty (S)
初始条件:串 S 存在。
操作结果:若 S 为空串,则返回true,否则返回 false。
StrCompare (S, T)
初始条件:串 S和T存在。
操作结果:若S > T,则返回值> 0;若S = T,则返回值= 0;若S < T,则返回值< 0。
StrLength (S)
初始条件:串 S 存在。
操作结果:返回 S 的元素个数,称为串的长度。
Concat (&T, S1, S2)
初始条件:串 S 1和S2存在。
操作结果:用T返回由S1和S2联接而成的新串。
SubString (&Sub, S, pos, len)
初始条件:串 S 存在,1≤pos≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1。
操作结果:用Sub返回串S的第 pos 个字符起长度为len的子串。
Index (S, T, pos)
初始条件:串S和T存在,T是非空串,1≤pos≤StrLength(S)。
操作结果:若主串 S 中存在和串 T 值相同的子串, 则返回它在主串 S 中第pos个字符之后第一次出现的位置;否则函数值为0。
Replace (&S, T, V)
初始条件:串S, T和 V 均已存在,且 T 是非空串。
操作结果:用V替换主串S中出现的所有与(模式串)T相等的不重叠的子串。
StrInsert (&S, pos, T)
初始条件:串S和T存在,1≤pos≤StrLength(S)+1。
操作结果:在串S的第pos个字符之前插入串T。
StrDelete (&S, pos, len)
初始条件:串S存在1≤pos≤StrLength(S)-len+1。
操作结果:从串S中删除第pos个字符起长度为len的子串。
ClearString (&S)
初始条件:串S存在。
操作结果:将S清为空串。
} ADT String
在了解了串可以进行哪些基本操作之后,一起来看看这些操作的实现以及两种模式匹配算法的实现:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>引入头文件<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#include <stdio.h> //使用了标准库函数 printf(),scanf()
#include <stdlib.h> //使用了动态内存分配函数 malloc(),free()
#include <string.h> //使用了字符串处理函数strlen()
//>>>>>>>>>>>>>>>>>>>>>>>>>>>自定义符号常量<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#define OVERFLOW -2 //内存溢出错误常量
#define OK 1 //表示操作正确的常量
#define ERROR 0 //表示操作错误的常量
#define TRUE 1 //表示逻辑正确的常量
#define FALSE 0 //表示逻辑错误的常量
#define MAXSTRLEN 255 //最大串长
#define DestoryString ClearString //DestoryString()和ClearString()作用相同
//>>>>>>>>>>>>>>>>>>>>>>>>>>>自定义数据类型<<<<<<<<<<<<<<<<<<<<<<<<<<<<
typedef int Status; //状态参量
typedef char ElemType; //元素类型
// 串的定长顺序存储C语言表示
typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度,1号单元开始存储串值字符序列
//--------------------------串的主要操作------------------------------
/*
函数:Print
参数:ElemType e 待访问元素
返回值:无
作用:访问元素,也就是打印输出
*/
void Print(ElemType e){
//指定遍历方式为控制台输出
printf("%c",e);
}//Print
/*
函数:StrTraverse
参数:SString T 待访问元素
void(* Visit)(ElemType) 函数指针,可以指向一个函数
返回值:无
作用:(串遍历)打印输出串的内容
*/
void StrTraverse(SString T, void(* Visit)(ElemType)){
//依次遍历每个元素
for(int i = 1; i <= T[0]; i++) {
Visit(T[i]);
}//for
//输出换行,使结果美观
printf("n");
}//StrTraverse
/*
函数:StrAssign
参数:SString T 定长串,采用我们自定义的数据类型,0号单元存放串长,
字符数据从1号单元开始存储。
chars 指向存储字符类型数据的指针,即指向一个已经存在的字符串,
这个串采用C语言默认的方式,数据从0号单元开始存储,以'