数据结构与算法之数据结构 字符串复杂度 匹配 / 反转 / 查找

数据结构与算法阿木 发布于 2025-07-11 6 次阅读


摘要:

字符串是编程中常见的数据类型,对其进行高效的操作是提高程序性能的关键。本文将围绕字符串的复杂度,探讨匹配、反转和查找算法,分析其时间复杂度和空间复杂度,并提供相应的代码实现。

一、

字符串操作在编程中无处不在,如文本编辑、搜索引擎、数据校验等。高效处理字符串操作对于提高程序性能至关重要。本文将深入探讨字符串的匹配、反转和查找算法,分析其复杂度,并给出相应的代码实现。

二、字符串匹配算法

字符串匹配算法用于在主字符串中查找子字符串的位置。常见的匹配算法有:朴素算法、KMP算法、Boyer-Moore算法等。

1. 朴素算法

朴素算法是最简单的字符串匹配算法,其时间复杂度为O(nm),其中n为主字符串长度,m为子字符串长度。

python

def naive_match(s, p):


n, m = len(s), len(p)


for i in range(n - m + 1):


j = 0


while j < m and s[i + j] == p[j]:


j += 1


if j == m:


return i


return -1


2. KMP算法

KMP算法通过预处理子字符串,构建部分匹配表(也称为“失败函数”),从而避免不必要的比较。KMP算法的时间复杂度为O(n+m)。

python

def kmp_match(s, p):


n, m = len(s), len(p)


lps = [0] m


compute_lps(p, m, lps)


i, j = 0, 0


while i < n:


if p[j] == s[i]:


i += 1


j += 1


if j == m:


return i - j


elif i < n and p[j] != s[i]:


if j != 0:


j = lps[j - 1]


else:


i += 1


return -1

def compute_lps(p, m, lps):


length = 0


lps[0] = 0


i = 1


while i < m:


if p[i] == p[length]:


length += 1


lps[i] = length


i += 1


else:


if length != 0:


length = lps[length - 1]


else:


lps[i] = 0


i += 1


3. Boyer-Moore算法

Boyer-Moore算法通过预处理子字符串,构建坏字符表和好后缀表,从而跳过不必要的比较。Boyer-Moore算法的时间复杂度平均为O(n+m),最坏情况下为O(nm)。

python

def boyer_moore_match(s, p):


n, m = len(s), len(p)


bad_char = [-1] 256


build_bad_char_table(p, m, bad_char)


i, j = n - 1, m - 1


while i >= 0:


if bad_char[ord(s[i])] != -1 and bad_char[ord(s[i])] < j:


j = max(0, bad_char[ord(s[i])] - 1)


else:


if s[i] == p[j]:


i -= 1


j -= 1


else:


j = max(0, bad_char[ord(s[i])] - 1)


if j == -1:


return i - j


i -= 1


return -1

def build_bad_char_table(p, m, bad_char):


for i in range(256):


bad_char[i] = -1


for i in range(m - 1):


bad_char[ord(p[i])] = i


三、字符串反转算法

字符串反转算法用于将字符串中的字符顺序颠倒。常见的反转算法有:直接反转、双指针反转等。

1. 直接反转

直接反转算法通过交换字符串首尾字符,实现字符串反转。时间复杂度为O(n),空间复杂度为O(1)。

python

def reverse_string(s):


s = list(s)


i, j = 0, len(s) - 1


while i < j:


s[i], s[j] = s[j], s[i]


i += 1


j -= 1


return ''.join(s)


2. 双指针反转

双指针反转算法使用两个指针分别指向字符串首尾,交换两个指针所指向的字符,然后移动指针,直到两个指针相遇。时间复杂度为O(n),空间复杂度为O(1)。

python

def reverse_string(s):


s = list(s)


i, j = 0, len(s) - 1


while i < j:


s[i], s[j] = s[j], s[i]


i += 1


j -= 1


return ''.join(s)


四、字符串查找算法

字符串查找算法用于在主字符串中查找子字符串的位置。常见的查找算法有:暴力查找、二分查找等。

1. 暴力查找

暴力查找算法通过遍历主字符串,逐个比较子字符串,实现查找。时间复杂度为O(nm),空间复杂度为O(1)。

python

def brute_force_search(s, p):


n, m = len(s), len(p)


for i in range(n - m + 1):


j = 0


while j < m and s[i + j] == p[j]:


j += 1


if j == m:


return i


return -1


2. 二分查找

二分查找算法适用于有序字符串。通过比较中间字符与子字符串,判断子字符串是否存在于主字符串中。时间复杂度为O(logn),空间复杂度为O(1)。

python

def binary_search(s, p):


n, m = len(s), len(p)


left, right = 0, n - m


while left <= right:


mid = (left + right) // 2


if s[mid:mid + m] == p:


return mid


elif s[mid:mid + m] < p:


left = mid + 1


else:


right = mid - 1


return -1


五、总结

本文围绕字符串的复杂度,探讨了匹配、反转和查找算法。通过分析算法的时间复杂度和空间复杂度,以及提供相应的代码实现,帮助读者更好地理解字符串操作。在实际应用中,根据具体需求选择合适的算法,以提高程序性能。