目录
什么是 Levenshtein 距离?
Levenshtein 距离 是一种衡量两个字符串之间相似度的指标,它主要考量的是将一个字符串转换为另一个字符串所需要的插入、删除和替换操作的次数。
Levenshtein 距离涉及的操作主要有:
- 插入: 向字符串 A 中添加一个字符。
- 删除: 从字符串 A 中移除一个字符。
- 替换: 将字符串 A 中的一个字符替换成另一个字符。
> 让我们来看一个例子,假设我们有两个字符串,字符串 A: "kitten" 需要转换为字符串 B: "sitting"。我们需要计算出所需的最少操作次数。
>
> – kitten → sitten (将 "k" 替换为 "s")
> – sitten → sittin (将 "e" 替换为 "i")
> – sittin → sitting (在末尾插入 "g")
>
> 在这个例子中,我们一共进行了三次操作,因此这两个字符串之间的 Levenshtein 距离为 3。
- 上下界: 当且仅当两个字符串完全相同时,Levenshtein 距离为零(非负数)。对于长度分别为 m 和 n 的两个字符串,由于完全转换需要通过插入或删除来完成,它们之间最可能的 Levenshtein 距离最大值为 max(m, n)。
Levenshtein 距离的应用场景:
Levenshtein 距离在许多领域都有广泛的应用,例如:
- 自动纠错算法: 文本编辑器和各种即时通讯应用(如 Gboard、SwiftKey 键盘等)都会在其自动纠错功能中使用 Levenshtein 距离。
- 数据清洗: 在数据清洗和标准化任务中,它被广泛用于减少数据冗余,并识别数据挖掘过程中的相似记录。
- 数据聚类与分类: 在聚类任务中,用于识别相似记录并将其分组;而在分类任务中,则用于识别相似记录并为其打上类别标签。
与其他编辑距离度量的关系:
让我们看看 Levenshtein 距离与其他距离度量有何不同:
- Damerau-Levenshtein 距离: 它与 Levenshtein 距离非常相似,但它增加了一个额外的操作——相邻字符交换,使得总操作数变成了 4 种。
- 汉明距离: 它只能应用于长度相同的字符串,用于衡量对应位置上不同字符的数量。
接下来,让我们看看如何通过不同的方法来实现它:
1) 使用递归方法计算 Levenshtein 距离
> 为了计算 Levenshtein 距离,在递归技术中,我们将使用一个简单的递归函数。它会逐一检查两个字符串中的每个字符,并递归地执行插入、删除和替换操作。
下面是上述思路的具体实现:
#### C++ 实现
// C++ code for the above approach:
#include
using namespace std;
int levenshteinRecursive(const string& str1,
const string& str2, int m, int n)
{
// str1 is empty
if (m == 0) {
return n;
}
// str2 is empty
if (n == 0) {
return m;
}
if (str1[m - 1] == str2[n - 1]) {
return levenshteinRecursive(str1, str2, m - 1,
n - 1);
}
return 1
+ min({
// Insert
levenshteinRecursive(str1, str2, m, n - 1),
// Remove
levenshteinRecursive(str1, str2, m - 1, n),
// Replace
levenshteinRecursive(str1, str2, m - 1, n - 1)
});
}
// Drivers code
int main()
{
string str1 = "kitten";
string str2 = "sitting";
// Function Call
int distance = levenshteinRecursive(
str1, str2, str1.length(), str2.length());
cout << "Levenshtein Distance: " << distance << endl;
return 0;
}
#### Java 实现
import java.io.*;
public class Solution {
public static int levenshteinRecursive(String str1,
String str2, int m, int n) {
// str1 is empty
if (m == 0) {
return n;
}
// str2 is empty
if (n == 0) {
return m;
}
if (str1.charAt(m - 1) == str2.charAt(n - 1)) {
return levenshteinRecursive(str1, str2, m - 1, n - 1);
}
return 1 + Math.min(
// Insert
levenshteinRecursive(str1, str2, m, n - 1),
Math.min(
// Remove
levenshteinRecursive(str1, str2, m - 1, n),
// Replace
levenshteinRecursive(str1, str2, m - 1, n - 1)
)
);
}
public static void main(String[] args) {
String str1 = "kitten";
String str2 = "sitting";
int distance = levenshteinRecursive(str1, str2, str1.length(), str2.length());
System.out.println("Levenshtein Distance: " + distance);
}
}