数据结构:字符串

简介: 数据结构:字符串

1.字符串


字符串∶简称为串,是由零个或多个字符组成的有限序列。一般记为。


  • 字符串的长度︰字符串中字符的数目n称为字符串的长度。
  • 空串:零个字符构成的串也称为「空字符串」,它的长度为0,可以表示为" "。
  • 子串∶字符串中任意个连续的字符组成的子序列称为该字符串的「子串」。并且有两种特殊子串,起始于位置为0、长度为k的子串称为「前缀」。而终止于位置n -1、长度为k的子串称为「后缀」。
  • 主串:包含子串的字符串相应的称为「主串」。


举个例子:


str="Hello world"

在示例代码中,str是一个字符串的变量名称,Hello World则是该字符串的值,字符串的长度为11。该字符串的表示如下图所示∶

b04912d654ced83137512340547081cf_66e183803f9e70a8fc84ff89f8c0eb16.png


2.字符串的比较


2.1字符串的比较操作


字符串之间的大小取决于它们按顺序排列字符的前后顺序。比如字符串 str1 = "abc" 和 str2 = "acc",


它们的第一个字母都是 a,而第二个字母,由于字母 b 比字母 c 要靠前,所以 b < c,于是我们可以


说 "abc" < "acd" ,也可以说 str1 < str2。


字符串之间的比较是通过组成字符串的字符之间的「字符编码」来决定的。而字符编码指的是字符在对


应字符集中的序号。


对于两个不相等的字符串,我们可以以下面的规则定义两个字符串的大小:


  • 从两个字符串的第 0 个位置开始,依次比较对应位置上的字符编码大小。
  • 如果 str1[i] 对应的字符编码等于 str2[i] 对应的字符编码,则比较下一位字符。
  • 如果 str1[i] 对应的字符编码小于 str2[i] 对应的字符编码,则说明 str1 < str2。比如:"abc" <
  • "acc"。
  • 如果 str1[i] 对应的字符编码大于 str2[i] 对应的字符编码,则说明 str1 > str2。比如:"bcd" >
  • "bad"。
  • 如果比较到某一个字符串末尾,另一个字符串仍有剩余:
  • 如果字符串 str1 的长度小于字符串 str2,即 len(str1) < len(str2)。则 str1 < str2。比如:"abc" < "abcde"。
  • 如果字符串 str1 的长度大于字符串 str2,即 len(str1) > len(str2)。则 str1 > str2。比如:"abcde" > "abc"。
  • 如果两个字符串每一个位置上的字符对应的字符编码都相等,且长度相同,则说明 str1 == str2,比如:"abcd" == "abcd"。


按照上面的规则,我们可以定义一个 strcmp 方法,并且规定:


  • 当 str1 < str2 时,strcmp 方法返回 -1。
  • 当 str1 == str2 时,strcmp 方法返回 0。
  • 当 str1 > str2 时,strcmp 方法返回 1。


2.2字符串比较代码


def strcmp (str1, str2):
    index1, index2 = 0,0
    while index1< len(str1 ) and index2< len(str2):
        if ord(str1 [index1] )== ord(str2 [ index2 ]):
            index1 += 1
            index2 += 1
    elif ord(str1[ index1])< ord(str2 [index2]):
        return -1
    else:
        return 1
    if len (str1)< len(str2) :
        return-1
    elif len(str1)> len (str2):
        return 1
    else:
        return 0


2.3字符串的字符编码


以计算机中常用字符使用的 ASCII 编码为例。最早的时候,人们制定了一个包含 127 个字符的编码表


ASCII 到计算机系统中。ASCII 编码表中的字符包含了大小写的英文字母、数字和一些符号。每个字符


对应一个编码,比如大写字母 A 的编码是 65,小写字母 a 的编码是 97。后来又针对特殊字符,将


ASCII 扩展到了 256 位。


ASCII 编码可以解决以英语为主的语言,可是无法满足中文编码。为了解决中文编码,我国制定了


GB2312、GBK、GB18030 等中文编码标准,将中文编译进去。但是世界上有上百种语言和文字,各


国有各国的标准,就会不可避免的产生冲突,于是就有了 Unicode 编码。Unicode 编码最常用的就


是 UTF-8 编码,UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成 1 ~ 6 个字节,常用的


英文字母被编码成 1 个字节,汉字通常是 3 个字节。


2.4字符串的存储结构


字符串的存储结构跟线性表相同,分为「顺序存储结构」和「链式存储结构」。

63a19c782a182b08bda66ce17e821a98_1e4f25f11e71c137c955be295d14ed0f.png

dff6f0d616d90c6a481bfa0946b65c15_833c4a47b8f9b9e0b196b646ee83cf75.png


3.字符串匹配问题


字符串匹配:又称「模式匹配」。可以简单理解为,给定字符串 T 和 p,在主串 T 中寻找子串 p。主


串 T 又被称为「文本串」,子串 p 又被称为「模式串」。


在字符串问题中,最重要的问题之一就是字符串匹配问题。而按照模式串的个数,我们可以将字符串匹


配问题分为:「单模式串匹配问题」和「多模式串匹配问题」。


3.1单模式串匹配问题


单模式匹配问题︰给定一个文本串T = tt2….tn,再给定一个特定模式串p = PPp2..pn。要求从文本串T找出特定模式串p的所有出现位置。


根据在文本中搜索模式串方式的不同,可以将单模式匹配算法分为以下三种:


  • 基于前缀搜索方法∶在搜索窗口内从前向后(沿着文本的正向)逐个读入文本字符,搜索窗口中文本和模式串的最长公共前缀。著名的KMP算法和更快的 Shift-Or算法使用的就是这种方法。


  • 基于后缀搜索方法:在搜索窗口内从后向前(沿着文本的反向)逐个读入文本字符,搜索窗口中文本和模式串的最长公共后缀。使用这种搜索算法可以跳过一些文本字符,从而具有亚线性的平均时间复杂度。最著名的 BM 算法,以及 Horspool 算法、Sunday 算法都使用了这种方法。


  • 基于子串搜索方法:在搜索窗口内从后向前(沿着文本的反向)逐个读入文本字符,搜索满足「既是窗口中文本的后缀,也是模式串的子串」的最长字符串。与后缀搜索方法一样,使用这种搜索方法也具有亚线性的平均时间复杂度。这种方法的主要缺点在于需要识别模式串的所有子串,这是一个非常复杂的问题。Rabin-Karp 算法、BDM 算法、BNDM 算法 和 BOM 算法使用的就是这种思想。其中,Rabin-Karp 算法使用了基于散列的子串搜索算法。


3.2多模式串匹配问题


多模式匹配问题∶给定一个文本串,再给定一组模式串,其中每个模式串是定义在有限字母表上的字符串。要求从文本串T中找到模式串集合Р中所有模式串的所有出现位置。


模式串集合Р中的一些字符串可能是集合中其他字符串的子串、前缀、后缀,或者完全相等。解决多模式串匹配问题最简单的方法是利用「单模式串匹配算法」搜索r遍。这将导致预处理阶段的最坏时间复杂度为1440093905d165559707baf8b03b0be6_0b7d31e09a84727d00ad34df89cd0cf3.png,搜索阶段的最坏时间复杂度为1d4eeea55034caae5bee75ea3009012a_cd08d5533cfe935d4678670e9eeb952e.png


如果使用「单模式串匹配算法」解决多模式匹配问题,那么根据在文本中搜索模式串方式的不同,我们也可以将多模式串匹配算法分为以下三种∶


  • 基于前缀搜索方法∶搜索从前向后(沿着文本的正向)进行,逐个读入文本字符,使用在P上构建的自动机进行识别。对于每个文本位置,计算既是已读入文本的后缀,同时也是P中某个模式串的前缀的最长字符串。著名的AC自动机算法、Multiple Shift-And算法使用的这种方法。


  • 基于后缀搜索方法∶搜索从后向前(沿着文本的反向)进行,搜索模式串的后缀。根据后缀的下一次出现位置来移动当前文本位置。这种方法可以避免读入所有的文本字符。Set Horspool算法、wu-Manber算法使用了这种方法。


  • 基于子串搜索方法︰搜索从后向前(沿着文本的反向)进行,在模式串的长度为min(len(p'))的前缀中搜索子串,以此决定当前文本位置的移动。这种方法也可以避免读入所有的文本字符。Multiple BNDM算法、SBDM算法、SBOM算法都使用了这种方法。

目录
相关文章
|
6月前
|
XML JSON NoSQL
Redis的常用数据结构之字符串类型
Redis的常用数据结构之字符串类型
56 0
|
3月前
|
存储 缓存 NoSQL
redis数据结构-字符串
redis数据结构-字符串
38 1
|
10天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
32 6
|
5月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
83 1
|
5月前
|
存储 JavaScript 前端开发
JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)
【6月更文挑战第25天】JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)。
40 2
|
5月前
数据结构 字符串 (第6天)
数据结构 字符串 (第6天)
|
5月前
|
存储 算法 Java
Java数据结构与算法:用于高效地存储和检索字符串数据集
Java数据结构与算法:用于高效地存储和检索字符串数据集
|
6月前
题目----数据结构线性表----字符串逆序
题目----数据结构线性表----字符串逆序
33 1
|
5月前
|
算法 Java
Java数据结构与算法:字符串匹配算法之暴力匹配
Java数据结构与算法:字符串匹配算法之暴力匹配
|
5月前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法