编辑距离
面试题
- 在一个长字符串中,寻找一个短字符串,短字符串可能有一些噪音,即有的字段不匹配,且短字符串是长字符串长度的百分之一左右,如何快速查找到这个短字符串。
- 当时面试官提示我编辑距离算法(
露怯了,压根没听说过),后来看了一下,发现其实就是一道经典的DP,哎 - 编辑距离算法衡量的是将一个字符串转换为另一个字符串所需的最少编辑操作次数,因为短字符串存在噪音,不会与长字符串中的子串完全匹配,所以我们可以筛选一定编辑次数内的子串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65public class EditDistanceSearch {
/**
* @param target 目标子串
* @param longString 长字符串
* @param threshold 容错阈值,即距离数,解决噪音问题
* @return
*/
public static List<String> findSimilarSubstrings(String target, String longString, int threshold) {
// 结果集
List<String> similarSubstrings = new ArrayList<>();
// 遍历长字符串
for (int i = 0; i < longString.length() - target.length(); i++) {
// 取等长子串,计算编辑距离
String substring = longString.substring(i, i + target.length());
int distance = calculateEditDistance(substring, target);
// 根据容错阈值筛选
if (distance <= threshold)
similarSubstrings.add(substring);
}
return similarSubstrings;
}
// 编辑距离算法
public static int calculateEditDistance(String str1, String str2) {
int m = str1.length();
int n = str2.length();
// 初始化矩阵
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
// 计算编辑距离
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j])) + 1;
}
}
}
return dp[m][n];
}
public static void main(String[] args) {
String target = "kitten";
String longString = "skittlesittingbingocat";
int threshold = 2;
List<String> similarSubstrings = findSimilarSubstrings(target, longString, threshold);
System.out.println("找到相似子串:");
for (String substring : similarSubstrings) {
System.out.println(substring);
}
}
}
概述
- 编辑距离(Edit Distance),也称为Levenshtein距离,是衡量两个字符串之间相似度的一种常用算法。它衡量的是将一个字符串转换为另一个字符串所需的最少编辑操作次数,其中编辑操作可以是插入、删除或替换字符。
- 其中一些常见的应用包括:
- 拼写纠错:通过计算目标单词与候选单词之间的编辑距离,可以找到最接近目标单词的正确拼写。
- 文本相似性:编辑距离可以用于比较两段文本之间的相似性,例如在文本搜索中匹配近似的关键词或在文档聚类中寻找相似的文本。
- 基因组比对:在生物信息学中,编辑距离可以用于比较DNA序列或蛋白质序列之间的相似性,从而进行基因组比对和分析。
- 语音识别:通过计算语音信号之间的编辑距离,可以在语音识别任务中找到最匹配的文本转录。
- 数据清洗:在数据处理中,可以使用编辑距离来清洗和规范化数据,例如纠正用户输入错误或匹配相似的实体名称。
- 力扣题目链接:https://leetcode.cn/problems/edit-distance/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length();
int n = word2.length();
int[][] dp = new int[m + 1][n + 1];
// 初始化
for (int i = 0; i <= n; i++) {
dp[0][i] = i;
}
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
// 计算编辑距离
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
}
}
return dp[m][n];
}
}
TODO
- 新增一个分类,用于记录工作中遇到的算法。
评论