数据结构(五):串

串的概念

  • 串(String)是由零个或多个字符组成的有限序列,又名字符串,一般记为 s = "a1a2...an"
  • 串中任意个数的连续字符组成的子序列称之为该串的子串,例如 "over" 是 "lover" 的子串

串的比较

  • "silly"、"stypid" 这样的两个字符串,第一个字母都是 "s",因此不存在差异,第二个字母由于 "i" 比 "t" 靠前,所以 "i"<"t",于是我们说 "silly" < "stypid"
  • 串的比较是通过组成串的字符之间的编码来进行的,而字符编码是指字符在对应字符集中的序号
  • 所以两个字符串是否相等,必须是它们串的长度以及每个字符豆相等时,才算是相等
  • 对于不相等的两个串,例如 s = "a1a2...an",t = "b1b2...bm",当满足以下条件之一时,s < t
    • n < m,且 ai = bi (i=1,2.....,n)
    • 当 s = "happen",t = "happy" 因为两串前 4 哥字母均相同,而第五个字母 e 的 ASCII 码是 101,y 的 ASCII 码是 121,e < y,所以 s < t

串的抽象数据类型

  • 串的逻辑结构和线性表很相似,不同之处在于串针对的是字符集,所有元素都是字符,因此串的基本操作与线性表有很大差别
  • 线性表更关注的是单个元素的操作,比如增删查一个元素,串中更多的是查找子串的位置、替换等操作
  • Data(数据元素):串中元素仅由一个字符组成,相邻元素具有前驱和后继关系
  • 基本操作
方法 描述
StrAssign(T,*chars) 生成一个其值等于字符串常量 chars 的串 T
StrCopy(T,S) 串 S 存在,由串 S 复制得串 T
ClearString(S) 串 S 存在,将串清空
StringEmpty(S) 若串 S 为空,返回 true、否则 false
StrLength(S) 返回串 S 元素个数,即长度
StrCompare(S,T) 若 S > T 返回值 > 0,若 S=T 返回 0,若 S < T 返回值 < 0
Concat(T,S1,S2) 用 T 返回由 S1 和 S2 联接而成的新串
Index(S,T,pos) 若 S 和 T 存在,T 是非空串,1 <= pos <= StrLength(S),若主串 S 中存在和串 T 值相同的子串,则返回它在主串 S 中第 pos 哥字符之后第一次出现的位置,否则返回 0
Replace(S,T,V) 串 S、T 和 V 存在,T 是非空串,用 V 替换主串 S 中出现的所有与 T 相等的不重叠的子串
StrDelete(S,pos,len) 串 S 存在,1 <= pos <= StrLength(S) - len + 1,从串 S 中删除第 pos 个字符起长度为 len 的子串
SubString(Sub,S,pos,len) 串 s 存在,1 <= pos <= StrLength(S),且 0 <= len <= StrLength(S) - pos +1 用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串

串的存储

顺序存储

  • 串的顺序存储结构是用一组地址连续的存储单元来存储串中的字符串序列,按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区
  • 一般可以将实际的串长度值保存在数组 0 下标位置,有的书中也会定义存储在数组的最后一个下标位置
  • 但有的编程语言觉得存个数字占空间麻烦,它规定在串值后面加一个结束标记,例如 "\0" ,这个时候如果想知道串长度,就需要遍历计算,但这其实还是需要占一个空间,何必呢?
  • 顺序存储方式存在些问题,比如两串的连接、新串的插入、以及字符串的替换都可能使得串序列长度超过数组长度

链式存储

  • 串的链式存储与线性表相似,但由于串结构的特殊性,结构中的每个元素数据都是一个字符,如果也简单的应用链表存储串值,一个结点对应一个字符,就会存在很大的空间浪费
  • 因此一个结点可以存放多个字符,最后一个结点若是未被占满时,可以用 "#" 或其它非串值字符补全
y4ABu.png
  • 此时一个结点存放多少个字符才合适变的很重要,这会直接影响串处理的效率,需根据实际情况做出选择
  • 但串的链式存储总的来说不如顺序存储灵活,性能也不如顺序存储结构好

朴素的模式匹配算法

  • 子串的定位操作通常称作串的模式匹配,假设要从主串 S = "goodgoogle" 中找到 T = "google" 子串为止,通常需要下面步骤:
    1. 主串 S 第一位开始,S 与 T 前三个字母都匹配成功,但 S 第四个字母匹配失败
    2. 主串 S 第二、三、四位开始,匹配失败
    3. 主串 S 第五位位开始,6 个字母全匹配成功
  • 简单的来说就是对主串的每一个字符作为子串开头,与要匹配的字符串进行匹配,对主串做大循环,内个字符开头做 T 的长度小循环,直到匹配成功或全部遍历完为止

效率问题

  • 最好的情况就是一开始就匹配成功,此时时间复杂度为 O(1)
  • 最差的时间复杂度为 O((n-m+1)*m),其中 n 是主串长度,m 为要匹配的子串长度
  • 朴素的模式匹配法效率十分低效

KMP 模式匹配算法

Ptj9X.png
  • 如果主串 S = "abcdefgab"、T = "abcdex" 那么如果用前面的朴素算法进行匹配,那么流程如下,在流程 ②③④⑤⑥ 中,首字符与子串 T 首字符均不等
  • 这似乎也是理所当然,"abcdex" 首字符 "a" 与后面的串 "bcdex" 任意一个字符都不相等,既然 "a" 不与自己后面的子串中任一字符相等,那么对于 ① 来说前 5 位字符分别相等,意味着子串 T 的首字符 "a" 不可能与 S 串的第 2 位到第 5 位的字符相等,因此 ②③④⑤⑥ 是多余的
  • 如果我们知道 T 串中首字符 "a" 与 T 中后面的字符均不相等(这是前提),而 T 串的第二位的 "b" 与 S 串中第二位的 "b" 相等,那么意味着 T 串中首字符 "a" 与 S 串中第二位 "b" 是不需要判断也知道它们不可能相等了,所以流程 ② 可以省略
  • 同样道理,在知道 T 串中首字符 "a" 与后面的字符不相等的前提下,T 串的 "a" 与 S 串后面的 "c"、"d"、"e" 也可以在流程 ① 之后确定不相等,所以流程 ②③④⑤⑥ 没有必要,只保留 ①⑥ 即可
  • 之所以保留 ⑥ 是因为在 ① 中 T [6] ≠ S[6],尽管我们知道 T[1] ≠ T[6],但不能断定 T[1] 一定不等于 S[6]
PtGOl.png
  • 如果 T 串后面也含有首字符 "a" 怎么办?
  • 假设 S = "abcabcabc"、T = "abcabx",前 5 个字符完全相等,第 6 个字符不等,此时根据刚才经验,T 的首字符 "a" 与 T 的第二、三位字符 "b"、"c" 均不等,所以不需要做判断,因此 ②③ 是多余的
  • 因为 T 的首位 "a" 与第四位 "a" 相等,第二位 "b" 与第五位 "b" 相等,而在 ① 时,第四位 "a" 与第五位 "b" 已经与主串 S 中相应位置比较过了,是相等的,因此可以判断,T 的首字符 "a"、第二位的 "b" 与 S 的第四位和第五位字符也不需要比较了,所以 ④⑤ 也可以省略
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • 十一期间,项目比较紧,让各位久等了 一.串的定义 串:是由零个或多个字符组成的有限序列,又名叫字符串一般记为s =...
    e40c669177be阅读 1,093评论 1 2
  • 课程介绍 先修课:概率统计,程序设计实习,集合论与图论 后续课:算法分析与设计,编译原理,操作系统,数据库概论,人...
    ShellyWhen阅读 2,252评论 0 3
  • 蓬蓬鼓声 掠水越山 把她带回那年初见 湿漉漉的少年 暮色下的眉眼 似一片云偶然投影她波间 只是朦胧的爱有太多阻拦 ...
    满架秋风扁豆花阅读 201评论 0 2
  • 片段一 身体绝对是革命的本钱,今上午到卫生所输液为身体质量加分。昨天晚上,儿子要开电风扇,我不同意!女儿要开空调,...
    甲午之印阅读 227评论 0 0
  • 每进来一个新来的客人,黄小厨,《深夜食堂》的老板,都会对客人说:菜单只有这些,你要是有特别喜欢和想要吃的,我能做的...
    周小北baby阅读 1,922评论 24 37