编辑距离(Minimum Edit Distance,MED),也叫 Levenshtein Distance。他的含义是计算字符串a转换为字符串b的最少单字符编辑次数。编辑操作有:插入、删除、替换(都是对a进行的变换)。用lev(i, j) 表示 a的前i个单词和 b的前j个单词的最短编辑距离(即从后往前)。可以分为以下几种情况:

  • i == 0j == 0

    • \(lev(i, j) = max(i, j)\)
  • i,j 不为0, 且 \(a[i] == a[j]\)
    • \(lev(i, j) = lev(i-1, j-1)\)
  • i,j 不为0, 且 \(a[i] != a[j]\)
    • 插入: \(lev(i, j-1)\)
    • 删除: \(lev(i-1, j)\)
    • 替换: \(lev(i-1, j-1) + 1\)
    • 三者取最小

这里的插入是在 a[i] 后方插入,这样,b[j] 已经和 a[i] 后方的元素匹配,所以j前移;删除表示删除当前元素,a[i] 前面的元素顶上来,所以i前移,但是顶上来的元素不一定和j匹配,所以j不动。

C++ 实现

解法就是动态规划:

class Solution {
public:
vector<vector<int>> matrix;
int editDistance(string str1, string str2) {
int len1 = str1.size();
int len2 = str2.size(); matrix = vector<vector<int>>(len1 + 1, vector<int>(len2 + 1, 0)); for (int i = 0; i <= len1; ++i)
matrix[i][0] = i; for (int j = 1; j <= len2; ++j)
matrix[0][j] = j; for (int i = 1; i <= len1; ++i) {
for (int j = 1; j <= len2; ++j) {
if (str1[i] == str2[j]) matrix[i][j] = matrix[i - 1][j - 1]; // 最后一个字母相同
else {
int insert = matrix[i][j - 1] + 1; // 插入
int del = matrix[i - 1][j] + 1; // 删除
int replace = matrix[i - 1][j - 1] + 1; // 替换
matrix[i][j] = min(insert, min(del, replace));
}
}
}
return matrix[len1][len2];
}
};

python-Levenshtein 库

pip install python-Levenshtein

import Levenshtein
print(Levenshtein.distance("the","teh"))

单词纠错

前几天看到一个很有意思的代码,通过统计的方式,计算最后可能的单词。w是输入单词,c是可能的正确单词。根据贝叶斯,按照惯例忽略分母。

\[p(c | w)=\frac{p(c) * p(w | c)}{p(w)}
\]
  • \(p(w|c)\) : 计算通过w所有编辑距离为i的所有正确单词(就是c),i越小表示p越大
  • \(p(c)\) : 在上面的c中,找出频率最高的单词
import re
from collections import Counter def words(text): return re.findall(r'\w+', text.lower()) WORDS = Counter(words(open('big.txt').read())) def P(word, N=sum(WORDS.values())):
# 返回单词的概率
return WORDS[word] / N def correction(word):
# 找到频率最高的c
return max(candidates(word), key=P) def candidates(word):
'''
找到候选单词c
'''
return (known([word]) or known(edits1(word)) or known(edits2(word)) or [word]) def known(words):
# 返回 words 和 WORDS的交集. 找出正确单词
return set(w for w in words if w in WORDS) def edits1(word):
# 编辑距离为1的所有单词
"All edits that are one edit away from `word`."
letters = 'abcdefghijklmnopqrstuvwxyz'
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [L + R[1:] for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1]
replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
inserts = [L + c + R for L, R in splits for c in letters]
return set(deletes + transposes + replaces + inserts) def edits2(word):
# 编辑距离为2的所有单词
return (e2 for e1 in edits1(word) for e2 in edits1(e1))

在python中 list1 or list2 的含义是:

  • 如果list1不为空,那么返回list1
  • 如果list1为空,那么返回list2

所以这行代码的意思是:

return (known([word]) or known(edits1(word)) or known(edits2(word)) or [word])
  • 如果单词是正确的就直接返回
  • 如果但是错的,就返回编辑距离是1的所有正确单词作为候选词
  • 如果编辑距离是1的正确单词没有,就返回编辑距离是2的所有正确单词作为候选词
  • 如果还是为空,就返回他自己

编辑距离(Minimum Edit Distance)的更多相关文章

  1. Minimum edit distance(levenshtein distance)(最小编辑距离)初探

    最小编辑距离的定义:编辑距离(Edit Distance),又称Levenshtein距离.是指两个字串之间,由一个转成还有一个所需的最少编辑操作次数.许可的编辑操作包含将一个字符替换成还有一个字符. ...

  2. Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance)

    Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可 ...

  3. 字符串编辑距离(Edit Distance)

    一.问题描述定义字符串编辑距离(Edit Distance),是俄罗斯科学家 Vladimir Levenshtein 在 1965 年提出的概念,又称 Levenshtein 距离,是指两个字符串之 ...

  4. stanford NLP学习笔记3:最小编辑距离(Minimum Edit Distance)

    I. 最小编辑距离的定义 最小编辑距离旨在定义两个字符串之间的相似度(word similarity).定义相似度可以用于拼写纠错,计算生物学上的序列比对,机器翻译,信息提取,语音识别等. 编辑距离就 ...

  5. 动态规划 求解 Minimum Edit Distance

    http://blog.csdn.net/abcjennifer/article/details/7735272 自然语言处理(NLP)中,有一个基本问题就是求两个字符串的minimal Edit D ...

  6. [Swift]LeetCode161. 一次编辑距离 $ One Edit Distance

    Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串S和T,确定它们是否都是是一 ...

  7. 编辑距离——Edit Distance

    编辑距离 在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤.不同的编辑距离中定义了不同操作的集合.比较常用的莱温斯坦距离(Le ...

  8. Min Edit Distance

    Min Edit Distance ----两字符串之间的最小距离 PPT原稿参见Stanford:http://www.stanford.edu/class/cs124/lec/med.pdf Ti ...

  9. LeetCode(72) Edit Distance

    题目 Given two words word1 and word2, find the minimum number of steps required to convert word1 to wo ...

随机推荐

  1. Debezium的基本使用(以MySQL为例)

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 一.Debezium介绍 摘自官网: Debeziu ...

  2. Taurus.MVC 微服务框架 入门开发教程:项目集成:5、统一的日志管理。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  3. 小A的树 - 树形DP

    题面 1 9 4 4 1 1 5 1 2 3 2 3 6 6 7 6 8 9 6 0 1 0 1 0 0 1 0 1 3 2 7 3 4 0 9 5 YES YES NO NO 题解 n <= ...

  4. 1.6_HTML基础属性

    name 属性 name 属性用于指定标签元素的名称. <a> 标签内必须提供 href 或 name 属性. <a name="value"> id 属性 ...

  5. 第四十六篇:工程化概念以及什么是webpack

    好家伙,这波是概念补充 1.什么是工程化概念? 我的开发: 开个项目,想怎么改怎么改,拉个东西过来就用 实际的前端开发: (1) 模块化(js的模块化,css的模块化,资源的模块化) (2) 组件化( ...

  6. PostgreSQL 时间函数分类与特性

    KingbaseES 时间函数有两大类:返回事务开始时间和返回语句执行时的时间.具体函数看以下例子: 1.返回事务开始时的时间 以下函数返回事务开始的时间(通过 begin .. end 两次调用结果 ...

  7. C++ 指针与二维数组名

    和一维数组类似,C++ 将二维数组名解释为其第一个元素的地址,而二维数组的第一个元素为一维数组,以下面的程序为例,二维数组名 array2d 和 &array2d[0] 等效,它们的类型都为 ...

  8. 注意了!这样用 systemd 可能会有风险

    在 Linux 6 / CentOS 6 中,使用 service 来进行服务的起停,但是在 Linux 7 / CentOS 7 中,替换为使用 systemctl 命令来控制.将一些常用应用注册成 ...

  9. axos在async模式下如何中断请求

    main.js import axios from 'axios' Vue.prototype.$http = axios Test.vue <template> <div clas ...

  10. 前端必读3.0:如何在 Angular 中使用SpreadJS实现导入和导出 Excel 文件

    在之前的文章中,我们为大家分别详细介绍了在JavaScript.React中使用SpreadJS导入和导出Excel文件的方法,作为带给广大前端开发者的"三部曲",本文我们将为大家 ...