数据结构(六)串存储结构

严格意义上讲,串存储结构也是一种线性存储结构,因为字符串中的字符之间也具有"一对一"的逻辑关系。只不过,与之前所学的线性存储结构不同,串结构只用于存储字符类型的数据。

存储一个字符串,数据结构包含以下3中具体存储结构:

1.定长顺序存储 :使用静态数组存储(定长,提前开辟内存空间)字符串。
2.堆分配存储:使用动态数组存储字符串。
3.块链存储:使用链表存储字符串。

定长顺序存储

串的定长顺序存储结构,可以简单地理解为采用 "固定长度的顺序存储结构" 来存储字符串,因此限定了其底层实现只能使用静态数组。

用定长顺序存储结构存储字符串时,需结合目标字符串的长度,预先申请足够大的内存空间。

char[] str = {'a','b','c','d','e'};

根据实际情况,实现代码可包含一些函数,用于实现某些具体功能,如求字符串的长度等,由于这些知识都是学习编程语言的基础内容,因此不再过多赘述。

堆分配存储结构

串的堆分配存储,其具体实现方式是采用动态数组存储字符串。
java中貌似没有这种字符串结构,String类中char[] 是final的 不允许变化。(StringBuilder不清楚)所以此处不做研究。

串的块链存储结构

串的块链存储,指的是使用链表结构存储字符串。
示例中实现串的块链存储使用的是无头节点的单链表。当然根据实际需要,也可以使用其它链表的结构(双向链表还是单链表,有无头节点)。

例如,图1 所示是用链表存储字符串 shujujiegou,该链表各个节点中可存储 1 个字符:

图1:各节点仅存储1个数据元素的链表

同样,图 2 设置的链表各节点可存储 4 个字符:


图2:各节点存储4个数据元素的链表

从图 2 可以看到,使用链表存储字符串,其最后一个节点的数据域不一定会被字符串全部占满,对于这种情况,通常会用 '#' 或其他特殊字符(能与字符串区分开就行)将最后一个节点填满。

链表各节点存储数据个数的多少可参考以下几个因素:

1.串长度和存储空间大小:若串包含数据量很大,且链表申请的存储空间有限,此时应尽可能让各节点存储更多的数据,提高空间利用率。

2.程序实现功能:如果实际场景中需要对存储的串做大量拆入或删除操作,则应尽可能减少各节点存储数据的数量。

以上两点仅是目前想到影响节点存储数据个数的因素,在实际场景中,还需结合实现环境综合分析。


串模式匹配算法

串的模式匹配算法,通俗地理解,是一种用来判断两个串之间是否具有"主串与子串"关系的算法。
实现串的模式匹配的算法主要有以下两种:

  • 1.普通的模式匹配算法,BF算法 (Brute Force)暴风算法
  • 2.快速模式匹配算法 KMP算法(Knuth-Morris-Pratt 三个发明者的名字)

BF算法原理

普通模式匹配算法,其实现过程没有任何技巧,就是简单粗暴地拿一个串同另一个串中的字符一一比对,得到最终结果。

首先,将串 A 与串 B 的首字符对齐,然后逐个判断相对的字符是否相等,如图3 所示:


图3:串的第一次匹配

图 3 中,由于串 A 与串 B 的第 3 个字符匹配失败,因此需要将串 A 后移一个字符的位置,继续同串 B 匹配,如图 4 所示:


图4:串的第二次匹配

图 4 中可以看到,两串匹配失败,串 A 继续向后移动一个字符的位置,如图 5 所示:


图5:串的第三次匹配

图 5 中,两串的模式匹配失败,串 A 继续移动,一直移动至图 6 的位置才匹配成功:


图6:串的第四次匹配

:

BF算法的时间复杂度

该算法最理想的时间复杂度 O(n),n 表示串 A 的长度,即第一次匹配就成功。
F 算法最坏情况的时间复杂度为 O(n * m),n 为串 A 的长度,m 为串 B 的长度。例如,串 B 为 "0000000001",而串 A 为 "01",这种情况下,两个串每次匹配,都必须匹配至串 A 的最末尾才能判断匹配失败,因此运行了 n * m 次。

BF 算法的实现过程很 "无脑",不包含任何技巧,在对数据量大的串进行模式匹配时,算法的效率很低。


KMP算法(快速模式匹配算法)

快速模式匹配算法,简称 KMP 算法,是在 BF 算法基础上改进得到的算法。

KMP 算法,它的实现过程接近人为进行模式匹配的过程。例如,对主串 A("ABCABCE")和模式串 B("ABCE")进行模式匹配,如果人为去判断,仅需匹配两次。


图7:第一次认为匹配模式

第一次如图 7 所示,最终匹配失败。但在本次匹配过程中,我们可以获得一些信息,模式串中 "ABC" 都和主串对应的字符相同,但模式串中字符 'A' 与 'B' 和 'C' 不同。

因此进行下次模式匹配时,没有必要让串 B 中的 'A' 与主串中的字符 'B' 和 'C' 一一匹配(它们绝不可能相同),而是直接去匹配失败位置处的字符 'A' ,如图 8 所示:


图8:第二次人为模式匹配

由此可以看出,每次匹配失败后模式串移动的距离不一定是 1,某些情况下一次可移动多个位置,这就是 KMP 模式匹配算法
KMP算法在此只做简述,(主要有点复杂,懒得写了)不做展开讲解。
另外还有Sunday和BM算法 建议使用Sunday算法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容