转载请标注原链接: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. mpu

    #include "mpu.h" #include "mem.h" #include "my_errno.h" #include " ...

  2. PHP干货技巧文,一些PHP性能的优化

    PHP优化对于PHP的优化主要是对php.ini中的相关主要参数进行合理调整和设置,以下我们就来看看php.ini中的一些对性能影响较大的参数应该如何设置. # vi /etc/php.ini (1) ...

  3. Visual Studio 2015 新建MVC项目 Package Manager Console不能使用 (HRESULT: 0x80131500)

    Visual studio 2015 突然新建不了MVC项目,报出错误: HRESULT: 0x80131500 在折腾了很长时间,最后在Github上看到这样一个贴 地址:https://githu ...

  4. git 的基本命令

    ...git init ...git add ...git commit -m "first commit" ...git remote add origin https://gi ...

  5. python网络编程【二】(使用UDP)

    UDP通信几乎不使用文件对象,因为他们往往不能为数据如何发送和接受提供足够的控制.下面是一个基本的UPD客户端: #!/usr/bin/env python import socket,sys hos ...

  6. Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)

    http://codeforces.com/contest/737 A: 题目大意: 有n辆车,每辆车有一个价钱ci和油箱容量vi.在x轴上,起点为0,终点为s,中途有k个加油站,坐标分别是pi,到每 ...

  7. C++ 之引用

    int argc ,char * argv[] - argument count & argument vector argc - 命令行参数个数,argv[]依次指向每一个命令行参数,其中a ...

  8. ittun配置和使用教程

    有好久没写博了.时间过得真快,一下子一年又过去了. 不墨迹这么多了. 作为一个前端,页面写好了少不了做测试以及给其他同事看看效果,然而公司没有测试服务器,真是悲催哦. 一直都是用ip地址看页面的.但是 ...

  9. 第一篇:Retrofit主要类UML图

    2016-05-06 16:07:09 1.先上一张Retrofit的代码结构图: 可以看到,Retrofit自身的结构很简单,代码量也不是很大.红色框部分是一些注解类,就是一些标记. 简单的看一下客 ...

  10. ShellShock 攻击实验

    一. 实验描述 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发.在本实验中,学生需要亲手重现攻击来理解该漏洞,并回答一些问 ...