编辑距离(Edit Distance | Levenshtein距离)

1.问题定义

编辑距离又称为Levenshtein距离,是指两个字符串之间,从一个字符串变成另一个字符串所需要的最小编辑操作次数。可以采用的编辑操作包括:插入操作、替换操作和删除操作。例如:字符串“a“ 与字符串 ”b“的编辑距离为1,只有一个替换操作。
将”kitten一字转成“sitting”的编辑距离为3:
sitten (k→s):替换操作
sittin (e→i):替换操作
sitting (→g):插入操作

2.问题分析

编辑距离问题可以采用动态规划的方式来解决。假设dp[i][j]表示字符串的长度为i的字符串strA[0...i-1]和字符串长度为j的字符串strB[0...j-1]的编辑距离。接下来就要分析dp[i][j]与dp[i-1][j-1]、dp[i-1][j]、dp[i][j-1]之间的关系。
假设strA的最后一个字符为‘x’,strB的最后一个字符为‘y’,则通过‘x’与‘y’的关系得到如下:
1)如果x==y,则dp[i][j]=dp[i-1][j-1];
2)如果x!=y,将x替换为y,则dp[i][j]=dp[i-1][j-1]+1;
3)如果x!=y,将y插入到x后面,则dp[i][j]=dp[i][j-1]+1;
4)如果x!=y,将x从strA中删除,则dp[i][j]=dp[i-1][j]+1;
在x!=y的情况下,dp[i][i]的值为2)3)4)中的最小值。
初始条件:
dp[i][0]=i,dp[0][j]=j.

3.程序实现

public class EditDistance {

	/**
	 * @author Qunzer
	 * @since 2013/12/16
	 */

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String strA = "hello";
		String strB = "helli1";
		System.out.println("Edit distance is :" + getEditDistance(strA, strB));

	}

	// 求解编辑距离的静态方法
	public static int getEditDistance(String strA, String strB) {
		int lenA = strA.length();
		int lenB = strB.length();
		int[][] dp = new int[lenA + 1][lenB + 1];
		int i, j;
		for (i = 0; i < lenA; i++) {
			dp[i][0] = i;
		}
		for (j = 0; j < lenB; ++j) {
			dp[0][j] = j;
		}
		for (i = 0; i < lenA; ++i) {
			char c1 = strA.charAt(i);
			for (j = 0; j < lenB; ++j) {
				char c2 = strB.charAt(j);
				if (c1 == c2)
					dp[i + 1][j + 1] = dp[i][j];
				else {
					int replaceTemp = dp[i][j] + 1;
					int insertTemp = dp[i + 1][j] + 1;
					int deleteTemp = dp[i][j + 1] + 1;
					dp[i + 1][j + 1] = getMin(replaceTemp, insertTemp,
							deleteTemp);
				}
			}
		}
		return dp[lenA][lenB];
	}

	// 得到三个中的最小值
	public static int getMin(int a, int b, int c) {
		int min = a > b ? b : a;
		return (c > min ? min : c);
	}

}

4.辑距离的应用

编辑距离可以用到以下场景:
DNA分析
拼字检查
语音辨识
抄袭侦测
相似度计算

你可能感兴趣的:(算法大杂侩)