1. 简介

本文是关于字符串相似性度量概述文章的延续,重点介绍以下三种基于序列的相似性度量方法

  • 最长公共子串(Longest Common Substring)
  • 最长公共子序列(Longest Common Subsequence)
  • Gestalt 模式匹配(Gestalt Pattern Matching)

其中,最长公共子串(LCS)最长公共子序列(LCSQ) 的主要区别在于:前者要求字符是连续的(即子串),而后者允许字符之间存在间隔(即子序列)。这两种方法都通过“公共长度”来衡量字符串的相似性。

Gestalt 模式匹配 则是基于最长公共子串递归地进行匹配,构建出一个更贴近人类认知的相似性度量。


2. 最长公共子串(Longest Common Substring)

在字符串相似性分析中,一种常用工具是找出两个字符串的最长公共子串(LCS)。公共子串越长,说明两个字符串越相似。

2.1. 动态规划实现

使用动态规划可以将时间复杂度优化到 **O(m × n)**,其中 m 和 n 分别是两个字符串的长度。该方法的核心是一个 (m+1) × (n+1) 的二维数组 dp,其中 dp[i][j] 表示以 X[i-1]Y[j-1] 结尾的最长公共子串长度。

✅ 动态规划状态转移:

if (X[i-1] == Y[j-1]) {
    dp[i][j] = dp[i-1][j-1] + 1;
} else {
    dp[i][j] = 0;
}

示例:

设两个字符串为:

  • X = "ABABC"
  • Y = "BABCA"

构造出的 DP 矩阵如下:

B A B C A
0 0 0 0 0 0
A 0 0 1 0 0 1
B 0 1 0 2 0 0
A 0 0 2 0 0 1
B 0 1 0 3 0 0
C 0 0 0 0 4 0

最大值为 4,对应的最长公共子串是 "ABCA"。


3. 最长公共子序列(Longest Common Subsequence)

与最长公共子串不同,最长公共子序列(LCSQ) 不要求字符连续。例如:

  • 句子 1:The fox jumped over the high fence
  • 句子 2:The quick brown fox jumped over the fence

最长公共子串是:

fox jumped over the

而最长公共子序列是:

The fox jumped over the fence

✅ 动态规划实现:

同样使用一个二维数组 dp[i][j] 表示 X 的前 i 个字符与 Y 的前 j 个字符的 LCSQ 长度。

if (X[i-1] == Y[j-1]) {
    dp[i][j] = dp[i-1][j-1] + 1;
} else {
    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}

时间复杂度同样是 **O(m × n)**。


4. Gestalt 模式匹配(Ratcliff/Obershelp)

Gestalt 模式匹配,也称 Ratcliff/Obershelp 相似性算法,是一种基于递归查找最长公共子串的字符串相似性度量方法。其核心公式如下:

$$ \text{Similarity} = \frac{2 \times K_m}{|S_1| + |S_2|} $$

其中:

  • $ K_m $ 是匹配字符的总数
  • $ |S_1| $ 和 $ |S_2| $ 分别是两个字符串的长度

✅ 匹配流程:

  1. 找出两个字符串的最长公共子串(LCS)
  2. 将字符串划分为左右两部分,在非匹配区域递归查找 LCS
  3. 累加所有匹配字符数 $ K_m $
  4. 套用公式计算相似度

示例:

比较两个字符串:

  • S1 = "Pennsylvania"
  • S2 = "Pencilvaneya"
  1. 初始 LCS 是 "lvan" → $ K_m = 2 × 4 = 8 $
  2. 左边匹配 "Pen" → $ K_m = 8 + 2 × 3 = 14 $
  3. 右边匹配 "a" → $ K_m = 14 + 2 × 1 = 16 $

最终相似度:

$$ \frac{2 \times 16}{12 + 12} = \frac{32}{24} = 0.66 $$

⚠️ 复杂度分析:

Gestalt 的时间复杂度依赖于 LCS 的实现,最坏情况下为 **O(n²)**,最好为 **O(n)**。


5. 小结

本文介绍了三种基于序列的字符串相似性度量方法:

方法 是否要求连续 时间复杂度 应用场景
最长公共子串(LCS) ✅ 是 O(m × n) 精确匹配、局部相似性
最长公共子序列(LCSQ) ❌ 否 O(m × n) 文本比较、模糊匹配
Gestalt 模式匹配 ❌ 否(递归 LCS) O(n²) 自然语言处理、模糊搜索

✅ 这些方法各有优劣,选择时应根据实际需求权衡:

  • 要求精确匹配 → 用 LCS
  • 允许字符间隔 → 用 LCSQ
  • 需要更贴近人类感知的相似度 → 用 Gestalt

这些算法在文本比对、拼写检查、模糊搜索等领域有广泛应用。


原始标题:String Similarity Metrics: Sequence Based