Edit Distance----hard

Given two words  word1 and  word2 ,find the minimun 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

Tips:Dynamic programming

动态规划(dynamic programming)通过把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解.动态规划算法通常用于求解问题最优解问题,此类问题通常有多个可行解,在寻找最优解得过程中,与分治法类似,将原问题化解成子问题,逐步解决子问题。
该问题类似可将问题简化为相似子问题,在子问题基础上逐步增加问题复杂程度

解法思路如下:
1.word1长度n,word2长度m
  定义D(i,j)为word1[1...i]与word2[1...j]间最短编辑路径长度,即word1中从开始到第i个字符的子字串,与word2从开始到第j个字符的子字串间的最短编辑路径长度,则最最终所求为D(n,m)
2.先计算D(0,0)即两个空字串间编辑长度=0;
   计算D(i,0) (i=1.....n)
D(i,0) = i;观察即知从长度为i的字串转化为空字串的编辑路径长度为i,即删去该i个字符
   计算D(0,j) (j=1.....m)
D(0,j) = j;同理从空字串转化为长度为j的字串只需增加该j个字符


3.当在原子问题结果上增加一个字符计算计算新子问题时产生如下讨论([A,B]---A、B分别表示两字串):
  (1)例...原子问题字串[I,空],[空,空],[空,E],由上图D(0,0)=0,D(0,1)=1,D(1,0)=1
    新子问题字串[I,E]即计算D(1,1)
    从[I,空]到[I,E]转化步长为1即D(1,1)=D(1,0)+1 ------插入操作
    从[空,E]到[I,E]转化步长为1即D(1,1)=D(0,1)+1 ------删除操作
    从[空,空]到[I,E]: 
若I == E,即新增的两字符相同,则D(1,1)=D(0,0)------无需操作
若I !== E,即新增的两字符不同,则D(1,1)=D(0,0)+1-------替换操作
    则D(1,1)即为
   归纳上述例子得如下迭代计算公式:
(图中+2应改为+1)
4.编写代码在程序中即可求得完整表


代码如下

import java.lang.Math;

public class Solution {
    public int minDistance(String word1, String word2) {
//取word1与word2长度,m,n,建立m+1,n+1二维数组
        int editDistance[][] = new int [word1.length()+1][word2.length()+1];
int i;
int j;
editDistance[0][0] = 0;
for(i=1;i<=word1.length();i++)
editDistance[i][0] = i;
for(j=1;j<=word2.length();j++)
editDistance[0][j] = j;
//从已取得的值基础上逐步增加单词长度
for(i=1;i<=word1.length();i++)
for(j=1;j<=word2.length();j++)
{
editDistance[i][j] = Math.min(editDistance[i-1][j]+1,editDistance[i][j-1]+1);
if(word1.charAt(i-1) == word2.charAt(j-1))
editDistance[i][j] = editDistance[i-1][j-1];
else
editDistance[i][j] = Math.min(editDistance[i][j],editDistance[i-1][j-1]+1);
}
        return editDistance[word1.length()][word2.length()];
    }
}

注意:
本题中对于三中操作的权重就设为1,实际情况中权重可根据相应情况做更改
附录:
详细解答 Stanford----- Edit Distance Minimun

===========================================================
再次看看别人的解答时候发现了更美妙的解法
空间复杂度O(m*n)+O(n)
思路同上述但再求数组中的值时方法略有不同

由于每次在完成一个位置的值时只需要其周围的三个已求位置的值,故可以每次保存周围三个数的值,从而只建立一个一维数组
通过不断滚动数组的值直到最后所求,代码如下
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class editdistance2 {
	public static void main(String[] args) throws IOException{
		String word1;
		String word2;
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
		word1 = read.readLine();
		//System.out.println(word1);
		word2 = read.readLine();
		//System.out.println(word2);
		System.out.println(minDistance(word1,word2));
	}
	
	public static int minDistance(String word1,String word2){
		int l1 = word1.length();
		int l2 = word2.length();
		
		if(l1==0)return l2;
		if(l2==0)return l1;
		
		int []editdis = new int[l1+1];
		for(int i=0;i<l1;i++)
			editdis[i]=i;
		
		
		int cur = 0;
		for(int j=1;j<=l2;j++){
			int pre = j-1;
			editdis[0] = pre+1;
			for(int k=1; k<=l1;k++){
				if(word1.charAt(k-1)==word2.charAt(j-1)) {
					cur = pre;
				}
				else{
					cur = Math.min(Math.min(editdis[k-1],editdis[k]),pre)+1;
				}
				pre = editdis[k];
				editdis[k] = cur;
			}
			editdis[l1]=cur;
		}

		return editdis[l1];
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值