编辑距离--计算字符串相似度

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

附 Java 代码
class editDistance { private String s1; private String s2; public editDistance(String s1,String s2) { this.s1 = s1; this.s2 = s2; } publicdouble getSimilarity() { int matrix[][]=newint[s1.length()+1][s2.length()+1]; int i,j; int cost=0; //初始化矩阵 for (i=0;i<=s1.length();i++) matrix[i][0]=i; for (j=0;j<=s2.length();j++) matrix[0][j]=j; for (i=1;i<=s1.length();i++)
定义: 相似度=1/(编辑距离+1),那么 kitten 和 sitting 的相似度就是 0.25 那么如何计算编辑距离呢? 编程之美上给的解法个人没看懂。 于是搜索出另外一种解法,简易明确。算法思路如下: 给出字符串 s1,字符串 s2,长度分别是 m 和 n。 ① 初始化:构造一个矩阵 distance,(m+1)×(n+1),其中第一行写上 0-m,第 一列写上 0-n。 ② 构造:给每个矩阵元素赋值,赋值规则如下,如果当前指向的 s1 和 s2 中的 元素相同,那么设 cost 为 0 否则为 1.比较当前赋值元素 current 的左边的 值(left),上面的值(top),左上角的值(left-top),取出最小值 min。如果 min 是 left 或 top,那么 current=min+1.否则 current=min + cost。 ③ 依次赋值,distance[m][n]就是两个字符串的编辑距离。
例子:
kitten 和 sitting 的距离矩阵如下:
原理:
为什可以这样做呢?为什么这样做能够求出两个字符串的编辑距离呢? 自己的考量如下,各位看官若有不对,不完善之处,恳请纠正。 ① 首先看初始化,第一行 0-m,显然是空字符到一个长度 m 的字符串的距离,就是依次加 上去呗!执行插入操作。第一列的值也是同样的道理。 ② 那么第二步构造是啥意思呢?为了简便起见,假设我们正在填 distance[3][3]。该点的值 无非是三种选择。 a) current = left+1 = 3 执行插入操作。依次变化为 ki->si->s->si b) current = top+1 = 3 执行删除操作。依次变化为 ki->si->sii->si c) current = left-top+cost = 1 不执行任何操作。依次变化为 ki->si。显然这种方式最优 用装逼语言描述如下: 设������1 = ������1 , … , ������������−1 , ������������ . ������2 = ������1 , … , ������������−1 , ������������ 。由������1 到������2 经过这三种途径(保证完备性) ① 由������1 , … , ������������ −1 , ������������ 到������1 , … , ������������−1 ,最后插入������������ ② 由������1 , … , ������������ −1 到������1 , … , ������������−1 , ������������ ,最后删除������������ ③ 由������1 , … , ������������ −1 到������1 , … , ������������−1 ,最后将������������ 改成������������ 这上述三种方式对应上面的 a,b,c 三种方式。因此我们取他们之间的最小值然后得到当 前距离可能能保持最小,即编辑距离。
编辑距离是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑
操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将 kitten 一字转成 sitting : ① sitten (k→s) ② sittin (e→i) ③ sitting (→g)
总共需要三次变换,那么他们之间的距离就是 3
{ for (j=1;j<=s2.length();j++) { //字符不等时,cost为1,否则为0 if (s1.charAt(i-1)!=s2.charAt(j-1)) cost=1; int left=matrix[i][j-1]; int top=matrix[i-1][j]; int left_top=matrix[i-1][j-1]; int min=(left<top)?left:top; matrix[i][j]=left_top<=min?(left_top+cost):(min+1); cost=0; } } int dis=matrix[i-1][j-1]; //System.out.println(dis); double sim=1-(double)dis/(s1.length()>s2.length()?s1.length():s2.length()); return sim; } publicstaticvoid main(String args[]) { String s1 = "apple"; String s2 = "applet"; editDistance ed = new editDistance(s1,s2); System.out.print("The similarity between s1 and s2 is:"); System.out.println(ed.getSimilarity()); } }
基于编辑距离求两个字符串的相似度
最近在编程之美这本书上看到这样一道题, 计算两个字符串的相似度。 首先得明确的是 两个字符串的相似度有很多定义,既有字符表面意义的,如 apple 和 applet 很接近只相差 1 个字符,但是意思相差很远,也有基于语义的,如 person 和 people,人的单复数,但是相 差了好几个字符。这里主要讨论字符表面意义的相似度。 在给出字符串表面意义的相似度之前首先给出编辑距离的概念。
Hale Waihona Puke
相关文档
最新文档