问题描述:

题目描述
Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
     a) Insert a character
     b) Delete a character
     c) Replace a character

算法分析:

也就是说,就是将一个字符串变成另外一个字符串所用的最少操作数,每次只能增加、删除或者替换一个字符。
首先我们令word1和word2分别为:michaelab和michaelxy(为了理解简单,我们假设word1和word2字符长度是一样的),dis[i][j]作为word1和word2之间的Edit Distance,我们要做的就是求出michaelx到michaely的最小steps。

首先解释下dis[i][j]:它是指word1[i]和word2[j]的Edit Distance。dis[0][0]表示word1和word2都为空的时候,此时他们的Edit Distance为0。很明显可以得出的,dis[0][j]就是word1为空,word2长度为j的情况,此时他们的Edit Distance为j,也就是从空,添加j个字符转换成word2的最小Edit Distance为j;同理dis[i][0]就是,word1长度为i,word2为空时,word1需要删除i个字符才能转换成空,所以转换成word2的最小Edit Distance为i。下面及时初始化代码:

for (int i = 0; i < row; i++) dis[i][0] = i;
       for (int j = 0; j < col; j++) dis[0][j] = j;

下面来分析下题目规定的三个操作:添加,删除,替换。
假设word1[i]和word2[j](此处i = j)分别为:michaelab和michaelxy
显然如果b==y, 那么dis[i][j] = dis[i-1][j-1]。
如果b!=y,那么:
添加:也就是在michaelab后面添加一个y,那么word1就变成了michaelaby,此时
dis[i][j] = 1 + dis[i][j-1];
上式中,1代表刚刚的添加操作,添加操作后,word1变成michaelaby,word2为michaelxy。dis[i][j-1]代表从word[i]转换成word[j-1]的最小Edit Distance,也就是michaelab转换成michaelx的最小Edit Distance,由于两个字符串尾部的y==y,所以只需要将michaelab变成michaelx就可以了,而他们之间的最小Edit Distance就是dis[i][j-1]。
删除:也就是将michaelab后面的b删除,那么word1就变成了michaela,此时
dis[i][j] = 1 + dis[i-1][j];
上式中,1代表刚刚的删除操作,删除操作后,word1变成michaela,word2为michaelxy。dis[i-1][j]代表从word[i-1]转换成word[j]的最小Edit Distance,也就是michaela转换成michaelxy的最小Edit Distance,所以只需要将michaela变成michaelxy就可以了,而他们之间的最小Edit Distance就是dis[i-1][j]。
替换:也就是将michaelab后面的b替换成y,那么word1就变成了michaelay,此时
dis[i][j] = 1 + dis[i-1][j-1];
上式中,1代表刚刚的替换操作,替换操作后,word1变成michaelay,word2为michaelxy。dis[i-1][j-1]代表从word[i-1]转换成word[j-1]的最小Edit Distance,也即是michaelay转换成michaelxy的最小Edit Distance,由于两个字符串尾部的y==y,所以只需要将michaela变成michaelx就可以了,而他们之间的最小Edit Distance就是dis[i-1][j-1]。
/*
if x == y, then dp[i][j] == dp[i-1][j-1]
if x != y, and we insert y for word1, then dp[i][j] = dp[i][j-1] + 1
if x != y, and we delete x for word1, then dp[i][j] = dp[i-1][j] + 1
if x != y, and we replace x with y for word1, then dp[i][j] = dp[i-1][j-1] + 1
When x!=y, dp[i][j] is the min of the three situations.
Initial condition:
dp[i][0] = i, dp[0][j] = j
*/
public class EditDistance
{
public int minDistance(String word1, String word2)
{
int len1 = word1.length();
int len2 = word2.length(); int dp[][] = new int[len1+1][len2+1];
for(int i = 0; i <= len1; i ++)//word1删除元素
{
dp[i][0] = i;
}
for(int j = 0; j <= len2; j ++)//word1插入元素
{
dp[0][j] = j;
} for(int i = 0; i < len1; i ++)
{
char c1 = word1.charAt(i);
for(int j = 0; j < len2; j ++)
{
char c2 = word2.charAt(j);
if(c1 == c2)
{
dp[i+1][j+1] = dp[i][j];
}
else
{
int insert = dp[i+1][j] + 1;
int delete = dp[i][j+1] + 1;
int replace = dp[i][j] + 1;
int min = insert>delete ? delete : insert;
min = min > replace ? replace : min;
dp[i+1][j+1] = min;
}
}
}
return dp[len1][len2];
}
}

 

EditDistance,求两个字符串最小编辑距离,动态规划的更多相关文章

  1. java实现字符串匹配问题之求两个字符串的最大公共子串

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 近期在项目工作中有一个关于文本对照的需求,经过这段时间的学习,总结 ...

  2. 求两个字符串的最长公共子串——Java实现

    要求:求两个字符串的最长公共子串,如“abcdefg”和“adefgwgeweg”的最长公共子串为“defg”(子串必须是连续的) public class Main03{ // 求解两个字符号的最长 ...

  3. SQLServer中求两个字符串的交集(字符串以符号分隔)

    两个字符串,以特定符号分隔(例如‘,’号),求交集 第一种情况: declare @m varchar(100),@n varchar(100)select @m=',2,3,5,7,8,9,10,' ...

  4. [URAL-1517][求两个字符串的最长公共子串]

    Freedom of Choice URAL - 1517 Background Before Albanian people could bear with the freedom of speec ...

  5. Python基础-求两个字符串最长公共前轴

    最长公共前缀,输入两个字符串,如果存在公共前缀,求出最长的前缀,如果没有输出no.如“distance”和“discuss”的最长公共前缀是“dis”. s1 = input('请输入第1个字符串-- ...

  6. 求两个字符串最长子串的LCS算法 C语言实现(简短的实现函数)

    /************************************************************************* > File Name: lcs.c > ...

  7. 求两个字符串最大的子字符串C#

    此代码由Java改写而来,字符串支持中文格式的. string str1 = "中国ab-15"; string str2 = "中国ab-23"; byte[ ...

  8. 求两个字符串的最长公共子串(LCS)

    http://tianyunpu2008.blog.163.com/blog/static/6559379920089162236915/

  9. 【java】求两个字符串的最长公共子串

    这个是华为OJ上的一道题目.首先,如果我们用java写代码,华为OJ有以下三条规则需遵守,否则编译无法通过或者用例无法通过,规则如下: (1)一定不可以有包名: (2)主类名只能为Main: (3)不 ...

随机推荐

  1. Linux中cp直接覆盖不提示的方法

    新做了服务器,cp覆盖时,无论加什么参数-f之类的还是提示是否覆盖,这在大量cp覆盖操作的时候是不能忍受的. 把a目录下的文件复制到b目录 cp –r a/* b 执行上面的命令时,b存在的每个文件都 ...

  2. 使用openssl模拟CA和CA证书的签发

    使用openssl模拟CA和CA证书的签发     当使用ssl/tls进行加密通信时,必须要有数字证书.若通信只限制在局域网内,可以不向第三方机构申请签发证书,可以通过openssl模拟CA(Cer ...

  3. SWT中ole/activex实践--操作word的一个例子

    http://setting.iteye.com/blog/747295 ———————————————————————————————————————————————— 这几年,做了很多word/e ...

  4. R语言中的factor

    对于初学者来说,R语言中的factor有些难以理解.如果直译factor为“因子”,使得其更加难以理解.我倾向于不要翻译,就称其为factor,然后从几个例子中理解: <span style=& ...

  5. r语言笔记 jn

    get_range <- function(data_name , row_name){ library(stringr) load(data_name) data_str <- str_ ...

  6. 引用dataframe的值为什么会不同

    在R语言中,通常有一些操作符可以来提取对象的子集,如以下三种: 1.“[” 单层方括号,返回的对象与原对象类型相同,它也可以返回一个对象中的多个元素: 2.“[[” 双层方括号,用来从列表(list) ...

  7. R语言如何将字符串转变为命令执行

    这里用到 eval() 和 parse() 函数.首先使用 parse() 函数将字符串转化为表达式(expression),而后使用 eval() 函数对表达式求解.x <- 1:10a &l ...

  8. Hive之分区(Partitions)和桶(Buckets)

    转自:http://www.aahyhaa.com/archives/316 hive引入partition和bucket的概念,中文翻译分别为分区和桶(我觉的不是很合适,但是网上基本都是这么翻译,暂 ...

  9. 在kali linux之下 下载并解压的文件名呈现乱码 解决方案

    从Linux往 windows拷贝文件或者从windows往Linux拷贝文件,有时会出现中文文件名乱码的情况,出现这种问题的原因是因为,windows的文件名中文编码默认为GBK,而Linux中默认 ...

  10. e827. 设置JSplitPane中分隔物的大小

    A divider can be no less than one pixel in size. // Create a left-right split pane JSplitPane pane = ...