-
最近研究一个两个字符串相识度的问题,结果发现了Levenshtein distance 算法,最早由俄国人发现,算法介绍可自行百度。仔细研究后发现其核心思想与动态规划极其相似,证明过程和实现细节可参考《算法导论》求最长字串的LCS这一章。这个在我的博客里也有记载。
Levenshtein Distance,<span class="wp_keywordlink_affiliate">编辑距离算法,是指从字符串A变成字符串B,所需的最少编辑(增,删,插入)次数。应用也相当广泛,这里我们用来求解两个字符串的相似度。
【例子】假设现在有源串“jary”与目标串“jerry”,求源串到目标串的<span class="wp_keywordlink_affiliate">编辑距离。
图解过程如下:
step 1:初始化如下矩阵
step 2:从源串的第一个字符(“j”)开始,从上至下与目标串进行对比
如果两个字符相等,则在从此位置的左,上,左上三个位置中取出最小的值;若不等,则在从此位置的左,上,左上三个位置中取出最小的值再加上1;
第一次,源串第一个字符“j” 与目标串的“j”对比,左,上,左上三个位置中取出最小的值0,因为两字符相等,所以加上0;接着,依次对比“j”→“e”,“j”→“r”,“j”→“r”,,“j”→“y” 到扫描完目标串。
step 3:遍历整个源串与目标串对比:
step 4:扫描完最后一列,则最后一个为最短编辑距离:
求出编辑距离,那么两个字符串的相似度 Similarity = (Max(x,y) - Levenshtein)/Max(x,y),其中 x,y 为源串和目标串的长度。
C#实现代码如下:
01.
public
static
int
LevenshteinDistance(
string
source,
string
target)
02.
{
03.
int
cell = source.Length;
04.
int
row = target.Length;
05.
if
(cell == 0) {
06.
return
row;
07.
}
08.
if
(row == 0) {
09.
return
cell;
10.
}
11.
int
[, ] matrix =
new
int
[row + 1, cell + 1];
12.
for
(var i = 0; i <= cell; i++) {
13.
matrix[0, i] = i;
14.
}
15.
for
(var j = 1; j <= row; j++) {
16.
matrix[j, 0] = j;
17.
}
18.
var tmp = 0;
19.
for
(var k = 0; k < row; k++) {
20.
for
(var l = 0; l < cell; l++) {
21.
if
(source[l].Equals(target[k])) tmp = 0;
22.
else
tmp = 1;
23.
matrix[k + 1, l + 1] = Math.Min(Math.Min(matrix[k, l] + tmp, matrix[k + 1, l]), matrix[k, l + 1] + 1);
24.
}
25.
}
26.
return
matrix[row, cell];
27.
}
28.
29.
public
static
float
StringSimilarity(
string
source,
string
target)
30.
{
31.
var ld = LevenshteinDistance(source, target);
32.
var maxLength = Math.Max(source.Length, target.Length);
33.
return
(
float
)(maxLength - ld) / maxLength;
34.
}
希望对一些朋友有用。
其实算法和结果知道了。我还是没搞明白为什么这样做可以计算得到相似度 。有更厉害的朋友欢迎指正。感谢博客园的兄弟。里面的大牛就是多,转自http://www.cnblogs.com/three-zone/archive/2013/06/06/LevenshteinDistance.html
-
编辑距离LCS算法详解:Levenshtein Distance算法计算两个字符串的相似度
最新推荐文章于 2023-01-13 09:44:31 发布