数据结构之串
Posted blknemo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之串相关的知识,希望对你有一定的参考价值。
串的存储结构
定长顺序存储表示
- 基本概念:
类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。在串的定长顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。 - 存储结构:
#define MAXLEN 255 //预定义最大串长为255
typedef struct
char ch[MAXLEN];//每个分量存储一个字符
int length; //串的实际长度
SString; //Sequential String
- 缺点:只能定长
堆分配存储表示
- 基本概念:
堆分配存储表示仍然以一组地址连续的存储单元存放串值得字符序列,但它们的存储空间是在程序执行过程中动态分配(堆分配)得到的。 - 存储结构:
typedef struct
char *ch; //按串长分配存储区
int length; //串的长度
HString; //Heap String
块链存储表示
- 基本概念:
类似于线性表的链式存储结构,也可采用链表方式存储串值。由于串的特殊性(每个元素只有一个字符),在具体实现时,每个结点既可以存放一个字符,又可以存放多个字符。每个结点称为块,整个链表称为块链结构。
串的基本操作
未完待续
串的模式匹配
BF算法
这是一种经典模式匹配算法,暴力破解(Brute-Force)算法
依次比较主串和模式串,若匹配失败,则主串指针回到刚开始比较的位置的下一个位置。
KMP算法
基本概念:
KMP(Knuth、Morris、Pratt三个人名)算法,KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。- 操作过程:
KMP算法主要是求解next数组。
next数组中存储的是部分匹配值(即 字符串前缀和后缀的最长相等前后缀长度)
\[next[j]= \begincases 满足p_1...p_i=p_j-i...p_j的最大i(<j)& \text最大i,最长相等前后缀长度\ 0& \text如果这样的i不存在 \endcases\]- 建立next数组;
- 每次匹配失败,就去找它的next值,令指针j指向next[j],继续比较。
通俗说明:
若当前部分匹配串的最后一位(即 最长相等后缀的最后一位)匹配失败,那么下一次匹配应该为最长相等前缀中的最后一位。其实很好理解,如果这段匹配失败了,那么就从头开始拿相同的部分(即 最长相等前缀)弥补过来,可以省去比较前后缀相同的部分,提高效率。next数组的计算:
KMP算法中的next函数值只和模式串有关,而和相匹配的主串无关。
首先我们给每个字符标上序号
模式串:abaabcac序号j 1 2 3 4 5 6 7 8 模式串S a b a a b c a c 之后,我们把模式串的所有前后缀依次列出来,求得每个子串中最长相等前后缀长度maxL(即 相等的前缀与后缀的最大长度)
序号j 1 2 3 4 5 6 7 8 模式串S a b a a b c a c maxL[j] 0 0 1 1 2 0 1 0 将maxL数组右移一位,第一个元素在右移以后空缺,用-1来填充;数组整体+1(右移+1)
序号j 1 2 3 4 5 6 7 8 模式串S a b a a b c a c maxL[j] 0 0 1 1 2 0 1 0 next[j] 0 1 1 2 2 3 1 2 - KMP算法的升级版--nextval[]
- 首先,第一个值填为0(nextval[1]=0作为特殊标记)
- 按序号依次检查maxL值和next值是否相等
- 若不相等,填入对应next值(nextval[k]=next[k])
- 若相等,填入对应序号为next值的nextval值(nextval[k]=nextval[next[k]])
序号j 1 2 3 4 5 6 7 8 模式串S a b a a b c a c maxL[j] 0 0 1 1 2 0 1 0 next[j] 0 1 1 2 2 3 1 2 nextval[j] 0 1 0 2 1 3 0 2
- 算法性能:
- 时间效率:O(n+m)
n为主串长度,m为模式串长度。
该算法遍历了主串,且避免了回溯。
- 时间效率:O(n+m)
以上是关于数据结构之串的主要内容,如果未能解决你的问题,请参考以下文章