一、串
1.串的定义
1) 串: 零个或多个任意字符组成的有限序列
2) 子串: 一个串中任意个连续字符组成的子序列(含空串)称为该串的子串
3) 真子串: 真子串是指不包含自身的所有子串
4) 主串: 包含子串的串相应的称为主串
5) 字符位置: 字符在序列中的序号为该字符在串中的位置
6) 子串位置: 子串第一个字符在主串中的位置
7) 空格串: 由一个或多个空格组成的串,与空串不同
8) 串相等: 当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,这两个串才是相等的
//所有的空串都是相等的
2.串的顺序存储结构
#define SIZE 20
typedef struct
{
char ch[SIZE+1]; //存储串的一维数组
int length; //串的当前长度
}str;
3.串的链式存储结构--块链结构(可将多个字符存放在一个结点中)
#define CHUNKSIZE 20
typedef struct Chunk
{
char ch[CHUNKSIZE]; //存放一个块中的字符
struct Chunk *next; //指向下一个块
}Chunk;
typedef struct
{
Chunk *head,*tail; //串的头指针和尾指针
int length; //串的当前长度
}LStr; //字符串的块链结构
4.串的模式匹配算法
算法目的: 确定主串中所含子串(模式串)第一次出现的位置(定位)
算法应用: 搜索引擎、拼写检查、语言翻译、数据压缩
算法种类: BF算法(Brute-Force,又称古典的、经典的、朴素的、穷举的)
KMP算法(特点:速度快)
1) 串的模式匹配算法--BF算法
算法思路: 从主串中的每一个字符开始依次与模式串的字符进行匹配
算法思想: 将主串的第pos个字符和模式串的第一个字符比较
//若相等,继续逐个比较后续字符
//若不相等,从主串的下一字符起,重新与模式串的第一个字符比较
直到主串的一个连续子串字符序列与模式串相等,返回值为主串中与模式串的子序列第一个字符的序号,即匹配成功
否则,匹配失败,返回值0
int Index_BF(str S, str T,int pos) //BF算法
{
int i = pos, j = 1; //从下标1开始存储字符串,下标0空出来
while (i <= S.length&&j <= T.length)
{
if (S.ch[i] == T.ch[j]) //主串和子串依次匹配下一个字符
{
i++;
j++;
}
else //主串和子串指针回溯重新开始下一次匹配
{
i = i - j + 2;
j = 1;
}
}
if (j > T.length)
return i - T.length; //返回匹配的第一个字符的下标
else
return 0; //模式匹配不成功
}
BF算法时间复杂度
例: S = "0000000001", T = "0001"
若n为主串长度,m为子串长度,最坏情况是
*主串前面n-m个位置都部分匹配到子串的最后一位,即这n-m位各比较了m次
*最后m位也各比较了1次
则总次数为: (n-m)*m+m = (n-m+1)*m
若m<<n,则算法复杂度O(n*m)
2) 串的模式匹配算法--KMP算法
KMP算法设计思想:
利用已经部分匹配的结果而加快模式串的滑动速度,且主串S的指针i不必回溯,可提速到O(n+m)