背景
在字符串处理、自然语言处理(NLP)、搜索引擎、拼写纠错、模糊匹配、DNA 序列分析等领域,编辑距离(Edit Distance) 是一个极其重要的算法。其中最经典、最广泛使用的就是 Levenshtein 距离算法。
Levenshtein 距离由俄罗斯数学家 Vladimir Levenshtein 在 1965 年提出,用于衡量两个字符串之间的相似程度。
什么是编辑距离?
编辑距离表示将字符串 A 转换为字符串 B 所需的最少编辑操作次数。
允许的三种基本操作:
- 插入(Insert)
- 删除(Delete)
- 替换(Replace)
举例说明
例 1:kitten → sitting
操作过程:
- kitten
- sitten (k → s 替换)
- sittin (e → i 替换)
- sitting (g 插入)
编辑距离 = 3
例 2:flaw → lawn
操作:
- flaw
- law (删除 f)
- lawn (插入 n)
编辑距离 = 2
需求
基础需求
实现函数:
func Levenshtein(a, b string) int
功能:
- 输入两个字符串
- 返回它们的编辑距离
- 支持 Unicode
- 时间复杂度 O(m*n)
输入输出示例
示例 1: 输入:"kitten", "sitting" 输出:3
示例 2: 输入:"flaw", "lawn" 输出:2
示例 3(Unicode): 输入:"你好", "您好" 输出:1
进阶需求
- 支持 Unicode
- 提供空间优化版本
- 提供企业级封装
- 提供可扩展版本(支持自定义操作权重)
技术原理
动态规划(Dynamic Programming)
Levenshtein 算法本质是二维动态规划问题。
定义: dp[i][j] = a 的前 i 个字符 与 b 的前 j 个字符 的最小编辑距离
状态转移方程:
如果 a[i-1] == b[j-1]: dp[i][j] = dp[i-1][j-1] 否则: dp[i][j] = min( dp[i-1][j] + 1, // 删除 dp[i][j-1] + 1, // 插入 dp[i-1][j-1] + 1 // 替换 )
时间复杂度
设 m = len(a), n = len(b)。
时间复杂度:O(m * n) 空间复杂度:O(m * n),可优化为 O(min(m, n))。
Unicode 处理
Go 字符串是 UTF-8 编码。必须转换为 []rune,否则中文会出错。
实现思路
-
转为 rune 数组 ra := []rune(a) rb := []rune(b)

