说明:
学习内容根据b站王卓老师视频学习记录
参考地址第02周08--2.4线性表的顺序表示和实现3_哔哩哔哩_bilibili
串
- 子串:一个串中任意个连续字符组成的子序列(含空串)称为该串的子串。
例如:“abcde”的子串有:
“”、“a”、“ab”、“abc”、“abcd”和“abcde”等
- 真子串:指不包含自身的所有子串;
- 主串:包含子串的串称为主串;
- 字符位置:字符在序列中的序号为该字符在串中的位置;
- 子串位置:子串第一个字符在主串中的位置;
- 空格串:由一个或多个空格组成的串,与空串不同;
- 串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相等时,这两个串才是相等的;
- 所有的空串是相等的。
串也分为顺序存储结构和链式存储结构:
顺序串:
顺序串的存储结构:
typedef struct{
char ch[MAXLEN + 1]; //存储串的一维数组
int length; //串的当前长度
}SString;
BF算法:
- 将主串的第pos个字符和模式串的第一个字符比较、
- 若相等,继续逐个比较后续字符;
- 若不等,从主串的下一字符起,重新与模式串的第一个字符比较。
//BF算法的描述
int Index_BF(SString S,SString T){ //设定S为主串,T为子串
int i = 1,j = 1;
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; //模式匹配不成功
}
KMP算法:
优点:利用已经部分匹配的结果而加快模式串的滑动速度,且主串S的指针i不必回溯,可提速到O(n+m)!
KMP算法在BF算法上做出了一些改进,增加了next[]数组来存放和子串先后相等数的位置值,方便子串的j在一定情况下不必溯回到位置为1的位置,大大缩短了时间。
下面代码为伪代码,在使用时需要做出一些改进,引用下get_next函数等
//求next[j]
void get_next(SString T,int &next[]){
int i = 1,j = 0;
next[1] = 0;
while (i<T.length){
if (j == 0 || T.ch[i] == T.ch[j]){
++i;
++j;
next[i] = j;
} else
j = next[j];
}
}
//KMP算法
int Index_KMP(SString S,SString T){ //设定S为主串,T为子串
int i = 1,j = 1;
while(i<=S.length && j<=T.length){
if (j == 0 || S.ch[i] == T.ch[j]){
++i;
++j; //主串和子串依次匹配下一个字符
} else{
j = next[j]; //i不变,j后退
}
}
if (j>=T.length)
return i-T.length; //返回匹配的第一个字符的下标
else
return 0; //模式匹配不成功
}
链式串:
链式串的块链结构:
#define CHUNKSIZE 80 //块的大小可由用户定义
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct {
Chunk *head,*tail; //串的头指针和尾指针
int curlen; //串的当前长度
}LString; //字符串的块链结构
数组:
本章暂时跳过,感觉和Java数组基本概念一致,如后续需要再补上
typedef elemtype array2[m][n];
//等价于
typedef elemtype array1[n];
typedef array2[m];
广义表:
- 表头:第一个元素;
- 表尾:除表头外的其他元素组成的表;
- 广义表的长度定义为最外层所包含元素的个数;
- 广义表的深度定义为该广义表展开后所含括号的重数;
- 广义表可以和其他广义表共享;
- 广义表可以是一个递归的表。
- 广义表是多层次结构。