前言:
这里我大概看了看王道的教材,毕竟学了人家的课,用人家的知识框架,所以提前说一下。肯定有的是根据王道教材或者是依据王道的思路来进行讲解的地方,在这里也感谢王道团队免费的开源课程,我从中学到很多。
1、串的基本概念:
(1)主串
串,也就是字符串,我们平时能看到这样的东西"asfasfsafcsacsac",这个双引号里面的东西,就是字符串,主串也就是长这个样子,这一整个串,就是主串。再说一点,就是这个双引号不算哈,并且,双引号内不光有字母,也可以有其他特殊字符和数字。
(2)子串
子串,顾名思义,也是串,但是他和主串有所不同的是,它只是主串的一部分,说明白点就是,从一个主串里,随便截下来一段,他都是子串,即使只有主串的一个字符,它都是子串。并且,还有个特殊的串->"",就是啥也没有的空串,它也属于主串的子串。
(3)串长
串长,我的理解,就是这个字符有多少个。
2、存储结构:
(1)定长顺序存储
#define MAX_SIZE 100
typedef struct {
char data[MAX_SIZE];
int length;
} SeqString;
结构体里面定义了一个数组和一个int数据,用int数据来充当指针的作用,在前几章也经常这样干,这是顺序存储的一种惯用手段。
(2)堆分配存储
typedef struct {
char *data;
int length;
} HeapString;
看到这个堆,很多人还不知道是什么东东,换句话说,咱们计算机里有很多个地方用来存储数据,现在就有一个地方叫做堆,他就是我们特别拿来存储数据的一个自由存储区,并且使用malloc函数和free函数来实现动态管理,前几章也用过malloc函数。
(3)块链存储
#define BLOCK_SIZE 64
typedef struct Block {
char data[BLOCK_SIZE];
struct Block *next;
} Block;
看到链子,很自然的脑海里想起单链表,但是这个和单链表有所不同,哪里不同?单链表的节点定义是数据域和指针域,他的数据域只能存储一个数据,但是我们这里却在里面定义了一个数组,那就能看出来,此时这里不再是节点,它是数组,数组和数组之间通过指针相连。
3、模式匹配算法(重点):
(1)概念
重点来了哦,重点哦。啥叫模式匹配?先知道模式匹配,然后再模式匹配算法。
模式匹配,也就是咱们的子串定位,在一个主串中找到我们子串(也叫模式串)第一次出现的位置。简单吧?
(2)暴力匹配
暴力匹配,所谓暴力,就是不动脑子,一个一个的比,一直直到找到为止。那我用文字描述一个例子,各位看能不能理解。现在我们的主串是"sdasfasfvdvafasfasdsa",咱们的模式串是"va",好吧开始匹配吧,第一次,va和sd比较,很明显不是,那下一个,da,也不是,那下一个as...就这样不懂脑子的比,一共对比11次,我终于找到了我需要的va,嘿嘿。
(3)KMP算法
这里的这个算法,我有点难以言述,就是我文字能力比较差,没办法讲的很清楚,建议读者先去大概看一下王道的视频,视频里有算法思想。
那我这里主要讲解两种next数组的求法,嘿嘿嘿。
我直接引用别人的解法吧,因为这是我个人觉得最清晰也是最能理解的解法了
next数组的两种处求解方式_计算next数组值-CSDN博客
(4)KMP算法的优化
优化,其实就是在next数组的基础上再进行优化,避免再进行一些重复的比较,所以,这里大概还是建议各位直接看视频讲解,因为我直接搬运别人的作品就很不道德,但是给各位指个方向的话又怕误导各位,如果有时间,我就专门录制一个视频,来给各位讲解一下kmp算法和优化思想以及next数组和nextval数组的手动求法。
致歉:
因为作者文笔有限,用文字也没办法说清楚kmp算法思想和next数组求解的过程,但是我自己又不屑于抄别人的文章(代码除外哈),所以特此我复试完之后我会专门录制一个视频来讲解这章遗漏的知识点。如果耽误了您的时间,又没给您带来帮助,我在这里对您说,不好意思。