Levenshtein字符串距离算法介绍
Levenshtein字符串距离算法介绍
文/开发部 Dimmacro
KMP完全匹配算法和 Levenshtein相似度匹配算法是模糊查找匹配字符串中最经典的算法,配合近期技术栏目关于算法的探讨,上期介绍了KMP算法的一些皮毛,收到了同事的一些反馈,本期再接再厉,搜集了一些资料,简单谈谈Levenshtein相似度匹配算法,希望能抛砖引玉。
算法简介:
Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,其原理是两个字符串之间,由一个经过许可的编辑操作转换成另一个所需的最少步骤。其中许可的编辑操作包括将替换一个字符,插入一个字符,删除一个字符。
概述:
如果要把两个不相同的字符串变得相同,可以通过如下操作方法:
1.修改一个字符(如把“a”替换为“b”)。
2.增加一个字符(如把“abdd”变为“aebdd”)。
3.删除一个字符(如把“travelling”变为“traveling”)。
比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加或者减少一个“g“的方式来达到目的。无论是增加还是减少,都仅需要一次操作。我们把两个不等字符串使之相等的操作次数定义为两个字符串的距离,这也是Levenshtein算法的核心原理。
如果有两个串A=xabcdae和B=xfdfa,它们的第一个字符是相同的,只要计算A[2,…,7]=abcdae和B[2,…,5]=fdfa的距离就可以了。但是如果两个串的第一个字符不相同,那么可以进行如下的操作(lenA和lenB分别是A串和B串的长度)
1.删除A串的第一个字符,然后计算A[2,…,lenA]和B[1,…,lenB]的距离。
2.删除B串的第一个字符,然后计算A[1,…,lenA]和B[2,…,lenB]的距离。
3.修改A串的第一个字符为B串的第一个字符,然后计算A[2,…,lenA]和B[2,…,lenB]的距离。
4.修改B串的第一个字符为A串的第一个字符,然后计算A[2,…,lenA]和B[2,…,lenB]的距离。
5.增加B串的第一个字符到A串的第一个字符之前,然后计算A[1,…,lenA]和B[2,…,lenB]的距离。
6.增加A串的第一个字符到B串的第一个字符之前,然后计算A[2,…,lenA]和B[1,…,lenB]的距离。
很明显,这是一个递归过程。
示例:
递归计算字符串” GUMBO”与” GAMBOL”的距离
1. 步骤1
设置n为字符串s即"GUMBO"的长度。设置m为字符串t即"GAMBOL"的长度。如果n等于0,返回m并退出。如果m等于0,返回n并退出。构造两个向量v0[m+1] 和v1[m+1],串联0..m之间所有的元素并初始化v0 to 0..m。如下图
|
v0 |
v1 |
|||||||||||||
|
G |
U |
M |
B |
O |
||||||||||
|
0 |
1 |
2 |
3 |
4 |
5 |
|||||||||
|
G |
1 |
|||||||||||||
|
A |
2 |
|||||||||||||
|
M |
3 |
|||||||||||||
|
B |
4 |
|||||||||||||
|
O |
5 |
|||||||||||||
|
L |
6 |
|||||||||||||
2. 步骤2
检查 s (i from 1 to n) 中的每个字符。
检查 t (j from 1 to m) 中的每个字符
如果 s[i] 等于 t[j],则编辑代价为 0;如s1=t1=G,所以第四行第三列为0
如果 s[i] 不等于 t[j],则编辑代价为1。s1=G,t2=A,所以第五行第三列为1。
如下图i=1;
|
v0 |
v1 |
|||||||||||||
|
G |
U |
M |
B |
O |
||||||||||
|
0 |
1 |
2 |
3 |
4 |
5 |
|||||||||
|
G |
1 |
0 |
||||||||||||
|
A |
2 |
1 |
||||||||||||
|
M |
3 |
2 |
||||||||||||
|
B |
4 |
3 |
||||||||||||
|
O |
5 |
4 |
||||||||||||
|
L |
6 |
5 |
||||||||||||
3. 步骤3
当 i = 2,其原理如步骤2,设置单元v1[j]为下面的最小值之一:
a、紧邻该单元上方+1:v1[j-1] + 1
b、紧邻该单元左侧+1:v0[j] + 1
c、该单元对角线上方和左侧+cost:v0[j-1] + cost(cost值为对角线上方即上一个字符比较结果,相等为0,不等为1)
如下图展示
|
v0 |
v1 |
|||||||||||||
|
G |
U |
M |
B |
O |
||||||||||
|
0 |
1 |
2 |
3 |
4 |
5 |
|||||||||
|
G |
1 |
0 |
1 |
|||||||||||
|
A |
2 |
1 |
1 |
|||||||||||
|
M |
3 |
2 |
2 |
|||||||||||
|
B |
4 |
3 |
3 |
|||||||||||
|
O |
5 |
4 |
4 |
|||||||||||
|
L |
6 |
5 |
5 |
|||||||||||
4. 步骤4
以此类推,当i=3,4,5,如下图:
|
v0 |
v1 |
|||||||||||||
|
G |
U |
M |
B |
O |
||||||||||
|
0 |
1 |
2 |
3 |
4 |
5 |
|||||||||
|
G |
1 |
0 |
1 |
2 |
3 |
4 |
||||||||
|
A |
2 |
1 |
1 |
2 |
3 |
4 |
||||||||
|
M |
3 |
2 |
2 |
1 |
2 |
3 |
||||||||
|
B |
4 |
3 |
3 |
2 |
1 |
2 |
||||||||
|
O |
5 |
4 |
4 |
3 |
2 |
1 |
||||||||
|
L |
6 |
5 |
5 |
4 |
3 |
2 |
||||||||
5. 步骤5
从上面的图可以看出,编辑距离就是矩阵右下角的值,v1[m]
== 2。由"GUMBO"变换为"GAMBOL"的过程对于我们来说是很直观的,即通过将"A"替换为"U",并在末尾追加"L"这样子(实际上替换的过程是由移除和插入两个操作组合而成的)。
用途:
· Spell checking(拼写检查)
· Speech recognition(语句识别)
· DNA analysis(DNA分析)
· Plagiarism detection(抄袭检测)
Levenshtein字符串距离算法介绍的更多相关文章
- iOS:使用莱文斯坦距离算法计算两串字符串的相似度
Levenshtein:莱文斯坦距离 Levenshtein的经典算法,参考http://en.wikipedia.org/wiki/Levenshtein_distance的伪代码实现的,同时参考了 ...
- Levenshtein distance 编辑距离算法
这几天再看 virtrual-dom,关于两个列表的对比,讲到了 Levenshtein distance 距离,周末抽空做一下总结. Levenshtein Distance 介绍 在信息理论和计算 ...
- Lucene的FuzzyQuery中用到的Levenshtein Distance(LD)算法
2019独角兽企业重金招聘Python工程师标准>>> Lucene的FuzzyQuery中用到的Levenshtein Distance(LD)算法 博客分类: java 搜索引擎 ...
- 扒一扒编辑距离(Levenshtein Distance)算法
最近由于工作需要,接触了编辑距离(Levenshtein Distance)算法.赶脚很有意思.最初百度了一些文章,但讲的都不是很好,读起来感觉似懂非懂.最后还是用google找到了一些资料才慢慢理解 ...
- 自然语言处理(5)之Levenshtein最小编辑距离算法
自然语言处理(5)之Levenshtein最小编辑距离算法 题记:之前在公司使用Levenshtein最小编辑距离算法来实现相似车牌的计算的特性开发,正好本节来总结下Levenshtein最小编辑距离 ...
- KNN算法介绍
KNN算法全名为k-Nearest Neighbor,就是K最近邻的意思. 算法描述 KNN是一种分类算法,其基本思想是采用测量不同特征值之间的距离方法进行分类. 算法过程如下: 1.准备样本数据集( ...
- Atitti knn实现的具体四个距离算法 欧氏距离、余弦距离、汉明距离、曼哈顿距离
Atitti knn实现的具体四个距离算法 欧氏距离.余弦距离.汉明距离.曼哈顿距离 1. Knn算法实质就是相似度的关系1 1.1. 文本相似度计算在信息检索.数据挖掘.机器翻译.文档复制检测等领 ...
- 推荐算法——距离算法
本文内容 用户评分表 曼哈顿(Manhattan)距离 欧式(Euclidean)距离 余弦相似度(cos simliarity) 推荐算法以及数据挖掘算法,计算"距离"是必须的~ ...
- ISP基本框架及算法介绍
什么是ISP,他的工作原理是怎样的? ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为 ...
随机推荐
- ubuntu16.04 安装opencv3
(opencvC++) luo@luo-ThinkPad-W540:20181205$ conda install --channel https://conda.anaconda.org/menpo ...
- jsp页面数据分页模仿百度分页效果
<%@page import="web09.shop.DBUtil"%> <%@page import="java.sql.ResultSet" ...
- JVM类加载机制详解
引言 如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 在加载阶段,虚拟机需要完成以下三件事情: 1)通过一个类的全限定名来获取定义此 ...
- fgetc()
fgetc() 函数从文件指针中读取一个字符.
- combotree 满足条件的节点不可选中
combotree: $("#Parent").treegrid("unselect");
- Android 修改 TextView 的全局默认颜色。
如果你的应用中大多数TextView的颜色是红色, 或者其他颜色, 你是为每一个TextView都设置一次颜色, 还是有其他更好的办法, 这里教你怎么修改TextView的默认颜色. 当然我们Text ...
- (2)WePHP 控制器与使用模板
<?php class C_index extends Action { public function __initialize() { echo"自动执行"; } pub ...
- SPOJ - AMR11A(DP)
Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did ...
- CodeForces 499D. Name That Tune(概率dp)
It turns out that you are a great fan of rock band AC/PE. Peter learned that and started the followi ...
- CodeForces 122G Lucky Array(一脸懵逼的树状数组)
Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal re ...