返回

Z 算法:高效的字符串搜索算法

IOS

Swift 算法学院 - Z-Algorithm 字符串搜索

参考

本篇是来自 Swift 算法学院的翻译的系列文章,Swift 算法学院致力于使用 Swift 实现各种算法,对想学习算法或者复习算法的同学非常有帮助,讲解思路非常清楚,每一篇都有详细的例子解释。更多翻译的文章还可以查看这里。最近几篇算法都是关于字符串查找的,而此次的算法…

导语

在本教程中,我们将介绍 Z 算法,它是一种高效的字符串匹配算法。Z 算法用于在文本中查找模式,并能够在 O(m + n) 的时间复杂度内完成,其中 m 是文本的长度,n 是模式的长度。

Z 算法的工作原理

Z 算法的工作原理是首先构建一个 Z 数组,其中 Z[i] 表示模式的前缀字符串与文本的前 i 个字符匹配的长度。Z 数组可以利用以下公式计算:

Z[i] = max(0, min(Z[i - 1], m - i))

其中 m 是文本的长度。

一旦我们构建了 Z 数组,就可以使用它来找到模式在文本中的所有匹配项。如果 Z[i] 等于模式的长度,则模式在文本中从第 i 个字符开始匹配。

实现

func zAlgorithm(text: String, pattern: String) -> [Int] {
  // 计算 Z 数组
  var z = Array(repeating: 0, count: text.count)
  z[0] = pattern.count
  var left = 0
  var right = 0
  for i in 1..<text.count {
    if i < right {
      z[i] = min(right - i, z[i - left])
    }
    while i + z[i] < text.count && pattern[z[i]] == text[i + z[i]] {
      z[i] += 1
    }
    if i + z[i] > right {
      left = i
      right = i + z[i]
    }
  }

  // 查找模式在文本中的所有匹配项
  var matches = [Int]()
  for i in 0..<text.count {
    if z[i] == pattern.count {
      matches.append(i - pattern.count + 1)
    }
  }

  return matches
}

性能

Z 算法是一种高效的字符串匹配算法,其时间复杂度为 O(m + n),其中 m 是文本的长度,n 是模式的长度。这使其适用于需要快速查找模式的应用,例如文本搜索和数据压缩。

优缺点

Z 算法是一种功能强大的字符串匹配算法,具有以下优点:

  • 高效:Z 算法的时间复杂度为 O(m + n),其中 m 是文本的长度,n 是模式的长度。
  • 易于实现:Z 算法的实现相对简单,易于理解和实现。
  • 多种应用:Z 算法可以用于多种应用,例如文本搜索、数据压缩和模式匹配。

Z 算法也存在以下缺点:

  • 较大的空间复杂度:Z 算法需要额外的空间来存储 Z 数组,其空间复杂度为 O(m),其中 m 是文本的长度。
  • 对模式不敏感:Z 算法对模式的顺序不敏感,这意味着它不能用于查找模式的变体。

扩展阅读