转载请标注原链接:http://www.cnblogs.com/xczyd/p/3808035.html

编辑距离概念描述

编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。一般情况下编辑操作包括:

  1. 将一个字符替换成另一个字符;
  2. 插入一个字符;
  3. 删除一个字符;

例如,将单词kitten转成单词sitting需要如下三个步骤:

  1. sitten (k→s)
  2. sittin (e→i)
  3. sitting (→g)

俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。

编辑距离的应用在信息检索、拼写纠错、机器翻译、命名实体抽取、同义词寻找等问题中有较多的应用

问题定义

求出任意两个字符串的编辑距离,即把一个字符串s1最少经过多少步操作变成编程字符串s2。其中操作有三种,添加一个字符,删除一个字符,修改一个字符

问题解析

首先定义这样一个函数——edit(i, j),它表示第一个字符串的长度为i的子串A到第二个字符串的长度为j的子串B的编辑距离。

可以利用如下动态规划公式来解析问题:

  1. 若 i = 0 且 j = 0,那么 edit(i, j) = 0
  2. 若 i = 0 且 j > 0,那么 edit(i, j) = j
  3. 若 i > 0 且 j = 0,那么 edit(i, j) = i
  4. 若 i ≥ 1 且 j ≥ 1,那么 edit(i, j) = min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) }

其中,当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。

第1,2,3个公式理解起来都比较容易,第4个公式其实列出了字符串i向字符串j转变的三种方式(自左向右依次为在字符串A的末尾删除一个字符,在字符串A的末尾添加一个与字符串B的末尾相同的字符,将字符串A末尾的字符替换为字符串B末尾的字符),然后分别计算其编辑距离,最后取其中的最小值。

Java代码

由上述动态规划公式,可以编写编辑距离的Java代码如下:

public int minDistance(String word1, String word2) {
//若两个字符串都为空时,编辑距离为0
if((word1==null||word1.length()==0)&&(word2==null||word2.length()==0)){
return 0;
}
//若其中一个字符串为空时,编辑距离为另一个字符串的长度
if(word1==null||word1.length()==0){
return word2.length();
}
if(word2==null||word2.length()==0){
return word1.length();
} //建立二维数组来保存所有的edit(i,j)
int[][] edit_distance = new int[word1.length()+1][word2.length()+1]; for(int i=0;i<word1.length()+1;i++){
edit_distance[i][0] = i;
}
for(int j=0;j<word2.length()+1;j++){
edit_distance[0][j] = j;
} //套入动态规划公式
for(int i=1;i<word1.length()+1;i++){
for(int j=1;j<word2.length()+1;j++){
int d1 = edit_distance[i-1][j]+1;
int d2 = edit_distance[i][j-1]+1;
int d3 = edit_distance[i-1][j-1]+
              (word1.charAt(i-1)==word2.charAt(j-1)?0:1);
edit_distance[i][j] = Math.min(d1,Math.min(d2,d3));
}
} return edit_distance[word1.length()][word2.length()];
}

相关博客

http://www.cnblogs.com/biyeymyhjob/archive/2012/09/28/2707343.html 有注解有图写的相当好

http://www.cnblogs.com/pandora/archive/2009/12/20/levenshtein_distance.html

编辑距离及其动态规划算法(Java代码)的更多相关文章

  1. 算法笔记1 - 编辑距离及其动态规划算法(Java代码)

    转载请标注原链接:http://www.cnblogs.com/xczyd/p/3808035.html 编辑距离概念描述 编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个 ...

  2. 动态规划算法(java)

    一.动态规划算法 众所周知,递归算法时间复杂度很高为(2^n),而动态规划算法也能够解决此类问题,动态规划的算法的时间复杂度为(n^2).动态规划算法是以空间置换时间的解决方式,一开始理解起来可能比较 ...

  3. 排序算法Java代码实现(一)—— 选择排序

    以下几篇随笔都是记录的我实现八大排序的代码,主要是贴出代码吧,讲解什么的都没有,主要是为了方便我自己复习,哈哈,如果看不明白,也不要说我坑哦! 本片分为两部分代码: 常用方法封装 排序算法里需要频繁使 ...

  4. 算法-java代码实现基数排序

    基数排序 第11节 基数排序练习题 对于一个int数组,请编写一个基数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素均小于等于2000. 测试样例: [1 ...

  5. 算法-java代码实现计数排序

    计数排序   第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3], ...

  6. 算法-java代码实现希尔排序

    希尔排序 第8节 希尔排序练习题 对于一个int数组,请编写一个希尔排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素小于等于2000. 测试样例: [1,2 ...

  7. 算法-java代码实现堆排序

    堆排序 第7节 堆排序练习题 对于一个int数组,请编写一个堆排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2 ...

  8. 算法-java代码实现快速排序

    快速排序 对于一个int数组,请编写一个快速排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] ...

  9. 算法-java代码实现归并排序

    归并排序 对于一个int数组,请编写一个归并排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] ...

随机推荐

  1. 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)

    1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...

  2. Java--静态区域块

    public class Demo3_2 { static int i=1; static //静态区域块 { //该静态区域块只被执行一次 System.out.println("a&qu ...

  3. scala 打印一个乘法口诀表 (<<scala 编程>> P87)

    (for(i <- 1 to 9;j <- 1 to i; s = s"$j*$i=${i*j}\t") yield {if(j==1) s"$s\n&quo ...

  4. php生成图片缩略图,支持png透明

    注:此功能依赖GD2图形库 PHP生成缩略图类   <?php /* * desc: Resize Image(png, jpg, gif) * author: 十年后的卢哥哥(http://w ...

  5. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  6. java获取当前时间前一周、前一月、前一年的时间

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar c = Calend ...

  7. python文本过滤

    #encoding:UTF-8 import re temp = "想做/ 兼_职/学生_/ 的 .加,我Q: 8 8. 8 8. !!?? 8 8 .8. 8. 8 有,惊,喜,哦&quo ...

  8. SVN使用说明

    一,安装客户端SVN 1.下载 "svn小乌龟"后,进行安装.如下图: 安装完成后,右键项目文件夹就可以看到如下: 2:checkout项目文件. 新建或者进入目录下(比如qian ...

  9. android 开发中 添加库文件 和so 文件的存放位置和添加依赖

    so文件一般存储在  main 当中  jniLibs 当中 然后在build.gradle中添加 sourceSets { main { jniLibs.srcDirs = ['src/main/j ...

  10. IOS中的编码规范

    1.指导原则 [原则1-]首先是为人编写程序,其次才是计算机. 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发.测试.生产.用户使用.版本升级和后期维护等长期过程,只有易读.易维护的软件代 ...