Leetcode刷题 - task2 - 字符串与字符串匹配(5 天)
1:字符串介绍
字符串(String):由零个或多个字符组成的有限序列。
一般如下记为:
s = a 1 a 2 … a n ( 0 ≤ n ⪇ ∞ ) s = a_1a_2…a_n (0 \le n ⪇ \infty) s=a1a2…an(0≤n⪇∞)
根据字符串的特点,我们可以将字符串问题分为以下几种:
- 字符串匹配问题;
- 子串相关问题;
- 前缀 / 后缀相关问题;
- 回文串相关问题;
- 子序列相关问题。
2:字符串比较问题
这里编写一个函数,输入是两个自定义的字符串格式的数据,输出一个可以衡量两个字符串的大小的结果。
想法:
两个字符串要么相等,要么不相等。
- 相等的时候:
- 字符串长度一致
- 字符串相应位置对应的字符一致
主要的点就是 字符串的长度 和 字符串各个位置所对应的字符 这两个点。整理一下,可以得到:
先根据两个字符串长度较小者(如果相等,就直接取其 len)的 len,进行相应位置对应的字符进行比较,会出现两种情况:
- 经过比较后,结果一致
- 经过比较后,直接区分出前者大或者前者小的结论
对于经过上面第一步比较后的结果一致的情况,再对两个字符串的长度进行比较,根据其长度比较的结果进行下结论:
- len(str_a) = len(str_b):两者相等
- len(str_a) > len(str_b):前者大
- len(str_a) < len(str_b):前者小
通过 Python语言 实现一下:
def str_compare(str_a: str, str_b: str) -> str:
min_len = min(len(str_a), len(str_b))
for i in range(min_len):
if ord(str_a[i]) == ord(str_b[i]):
continue
elif ord(str_a[i]) > ord(str_b[i]):
return str_a
else:
return str_b
if len(str_a) < len(str_b):
return str_b
elif len(str_a) > len(str_b):
return str_a
else:
return 'equal'
这里用到了 ord( ) 函数:
ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
其实也就是将字符串转换为可以比较的数值。
可以看一下老师的答案:
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
定义一个 strcmp
方法,并且规定:
- 当
str1 < str2
时,strcmp
方法返回-1
。 - 当
str1 == str2
时,strcmp
方法返回0
。 - 当
str1 > str2
时,strcmp
方法返回1
。
3:字符串的存储结构
字符串的存储结构跟线性表相同,分为「顺序存储结构」和「链式存储结构」。
「顺序存储结构」:
字符串的顺序存储结构是使用一组地址连续的存储单元依次存放串中的各个字符。按照预定义的大小,为每个定义的字符串变量分配一个固定长度的存储区域。一般是用定长数组来定义。
「链式存储结构」:
字符串的存储也可以采用链式存储结构,即采用一个线性链表来存储一个字符串。字符串的链节点包含一个用于存放字符的 data
变量,和指向下一个链节点的指针变量 next
。这样,一个字符串就可以用一个线性链表来表示。
在字符串的链式存储结构中,每个链节点可以仅存放一个字符,也可以存放多个字符。通常情况下,链节点的字符长度为 1
或者 4
,这是为了避免浪费空间。当链节点的字符长度为 4
时,由于字符串的长度不一定是 4
的倍数,因此字符串所占用的链节点中最后那个链节点的 data
变量可能没有占满,我们可以用 #
或其他不属于字符集的特殊字符将其补全。
字符串的链式存储将一组任意的存储单元串联在一起。链节点之间的逻辑关系是通过指针来间接反映的。
- Python 语言中使用
str
对象来代表字符串。str
对象一种不可变类型对象。即str
类型创建的字符串对象在定义之后,无法更改字符串的长度,也无法改变或删除字符串中的字符。
4:字符串匹配问题
字符串匹配(String Matching):又称模式匹配(Pattern Matching)。可以简单理解为,给定字符串 T
和 p
,在主串 T
中寻找子串 p
。主串 T
又被称为文本串,子串 p
又被称为模式串(Pattern
)。
在字符串问题中,最重要的问题之一就是字符串匹配问题。而按照模式串的个数,我们可以将字符串匹配问题分为:「单模式串匹配问题」和「多模式串匹配问题」。
「单模式串匹配问题」:
单模式匹配问题(Single Pattern Matching):给定一个文本串 T = t 1 t 2 . . . t n T = t_1t_2...t_n T=t1t2...tn,再给定一个特定模式串 p = p 1 p 2 . . . p n p = p_1p_2...p_n p=p1p2...pn。要求从文本串 T T T 找出特定模式串 p p p 的所有出现位置。
「多模式串匹配问题」:
多模式匹配问题(Multi Pattern Matching):给定一个文本串 T = t 1 t 2 . . . t n T = t_1t_2...t_n T=t1t2...tn,再给定一组模式串 P = p 1 , p 2 , . . . , p r P = {p^1, p^2, ... ,p^r} P=p1,p2,...,pr,其中每个模式串 p i p^i pi 是定义在有限字母表上的字符串 p i = p 1 i p 2 i . . . p n i p^i = p^i_1p^i_2...p^i_n pi=p1ip2i...pni。要求从文本串 T T T 中找到模式串集合 P P P 中所有模式串 p i p^i pi 的所有出现位置。
5:参考资料:
https://github.com/itcharge/LeetCode-Py/blob/main/Contents/06.String/01.String-Basic/01.String-Basic.md
https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896
https://leetcode.cn/leetbook/read/array-and-string/c9lnm/
https://oi-wiki.org/string/
https://www.cnblogs.com/traditional/p/13455962.html
https://www.runoob.com/python/python-func-ord.html
https://www.runoob.com/markdown/md-link.html