Levenshtein Distance算法java实现,英文单词相似度
2013-09-19 14:55
477 查看
昨儿突发奇想,想做一个关于英文单词按“形近词”分组的app,这个app最关键的就是这个“形近词”判断,经过思考和查资料,开始有了些眉目,看到了visionfans写的博客使用Matlab实现英文单词的"形近词"查找(http://blog.csdn.net/visionfans/article/details/6618652)就参照他的把算法用java实现了一下,效果出来了,但是很担心整个算法的效率问题,刚刚接触,对算法效率了解的甚少,还请大牛指点。
这个对两个单词“形近度”的判别是建立在一个矩阵上的,以本文为例,将两个单词存储在两个数组s1,s2中,然后根据两个数组的长度建立一个s2.length行s1.length列的矩阵,并将矩阵初始化,如图
下一步就是按照算法将这个矩阵中的数值填入,再填入之前,为了比较的时候方便,我们在这个矩阵外围把存在数组中的值加上,注意,仅仅是为了理解方便,真正的数组矩阵中不添加这一项,如下图蓝色区域:
比较过程:我们以橙色区域的数字为编号,“0”的坐标为(0,0)以此类推左上角第一个白色方块坐标为(1,1)……按咧进行匹配(即先将“a”分别同这一列的"s","a","r","r","n"进行比较,然后再以此向右进行)如果第一个单词的第一个字母(本例中的"a")与第二个单词的第一个字母(本例中的"s")相同,则定义的temp变量的值赋“0”否则赋“1”,然后这两个字母交集的区域(本例中坐标为(1,1))的数值取与之相邻的左,上,左上分别+1,+1,+temp如图:
然后向这三个值中的最小值赋给空白区域,作为其数值,按照这个方式把整个矩阵填满,然后矩阵中最后一个元素即最右下角的元素的数组就是两个单词的编辑距离也就是“区别度”,这个是指一个字符串A需要经过多少次编辑可以得到字符串B。
自己写了一个Java版的算法如下:
在理解了这个算法的运用时,遇到了一个疑问,就是这些矩阵中的每一个数字代表了什么,尤其是给矩阵初始化时填充的数字的用途。后来想到了一种解释,分享一下,如有错误欢迎指正。
我认为,矩阵的初始化的数字相当于标记了每个单词的位置,每个字母与同词的其他字母的相对位置是不变的,这个位置有什么用呢,我认为两个单词的编辑距离有2个分类,一个是相同位置但是字母不一样,需要一次编辑,另一个是相同字母不同位置,也需要一次编辑。
这里关于+1或者+temp我还没有研究出来,只是猜想的是字母匹配成功所要付出的代价“移位”、“插入”所需要的编辑次数,只是还没有研究明白,希望可以得到指点。万分感谢。
这个对两个单词“形近度”的判别是建立在一个矩阵上的,以本文为例,将两个单词存储在两个数组s1,s2中,然后根据两个数组的长度建立一个s2.length行s1.length列的矩阵,并将矩阵初始化,如图
下一步就是按照算法将这个矩阵中的数值填入,再填入之前,为了比较的时候方便,我们在这个矩阵外围把存在数组中的值加上,注意,仅仅是为了理解方便,真正的数组矩阵中不添加这一项,如下图蓝色区域:
比较过程:我们以橙色区域的数字为编号,“0”的坐标为(0,0)以此类推左上角第一个白色方块坐标为(1,1)……按咧进行匹配(即先将“a”分别同这一列的"s","a","r","r","n"进行比较,然后再以此向右进行)如果第一个单词的第一个字母(本例中的"a")与第二个单词的第一个字母(本例中的"s")相同,则定义的temp变量的值赋“0”否则赋“1”,然后这两个字母交集的区域(本例中坐标为(1,1))的数值取与之相邻的左,上,左上分别+1,+1,+temp如图:
然后向这三个值中的最小值赋给空白区域,作为其数值,按照这个方式把整个矩阵填满,然后矩阵中最后一个元素即最右下角的元素的数组就是两个单词的编辑距离也就是“区别度”,这个是指一个字符串A需要经过多少次编辑可以得到字符串B。
自己写了一个Java版的算法如下:
package englishword; public class Ledit { public static void main(String[] args) { char[] s1={'a','r','i','m'}; //预置单词 char[] s2={'s','a','r','r','n'}; int m=s2.length+1,n=s1.length+1; //矩阵 int[][] table=new int[m] ; // 矩阵的初始化 for(int i=0;i<n;i++){ table[0][i]=i; } for(int i=0;i<m;i++){ table[i][0]=i; } //算法开始,向矩阵中添加数值 for(int i=0;i<n-1;i++){ for(int j=0;j<m-1;j++){ int temp=0; if(s1[i]!= s2[j]) temp=1; else temp=0; table[j+1][i+1]=Min(table[j][i]+temp,table[j+1][i]+1,table[j][i+1]+1); } } //输出矩阵 for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ System.out.print(table[i][j]); System.out.print(","); } System.out.println(); } } private static int Min(int i, int j, int k) { // TODO Auto-generated method stub int[] tempSequence={i,j,k}; int min=i; for(int n=0;n<3;n++){ if(tempSequence <min){ min=tempSequence ; } } return min; } }
在理解了这个算法的运用时,遇到了一个疑问,就是这些矩阵中的每一个数字代表了什么,尤其是给矩阵初始化时填充的数字的用途。后来想到了一种解释,分享一下,如有错误欢迎指正。
我认为,矩阵的初始化的数字相当于标记了每个单词的位置,每个字母与同词的其他字母的相对位置是不变的,这个位置有什么用呢,我认为两个单词的编辑距离有2个分类,一个是相同位置但是字母不一样,需要一次编辑,另一个是相同字母不同位置,也需要一次编辑。
这里关于+1或者+temp我还没有研究出来,只是猜想的是字母匹配成功所要付出的代价“移位”、“插入”所需要的编辑次数,只是还没有研究明白,希望可以得到指点。万分感谢。
相关文章推荐
- 黑马程序员——输入英文单词变复数,java实现
- [NLP自然语言处理]计算熵和KL距离,java实现汉字和英文单词的识别,UTF8变长字符读取
- java实现读取一篇英文文章,统计其中每个单词出现的次数并排序输出
- 算法:将英文句子单词倒转实现(新方式)-Java
- 转:java写一个方法实现统计一条英文语句忠每个单词的个数
- Java实现英文句子中的单词顺序逆序输出的方法
- java实现英文单词单复数的相互转换
- java实现简单的英文文本单词翻译器功能示例
- 英文句子中单词翻转java实现
- 实现一个栈操作,将1~12月的英文单词压入栈中,然后再将其取出,使用Java代码实现(ERP软件公司2005.10)
- Java实现将数字日期翻译成英文单词的工具类实例
- Java实现对一行英文进行单词提取功能示例
- C语言实现英文语句中单词翻转
- 牛客网编程题:循环单词(Java实现)
- 推荐系统之余弦相似度及其Java实现
- 我的毕业测试题目(C语言实现英文单词zero~nine的加法)
- (11) Hadoop Java 实现MapReduce HelloWord 单词统计
- 《编程之美》读书笔记: 3.3 计算字符串的相似度(java实现)
- 用汉明距离进行图片相似度检测的Java实现
- Java实现正则匹配出script标签中字符串包含某个几个单词的所有行,以及编码转换