天天看点

最小编辑距离(字符串相似度)

编辑距离问题:又称Levenshtein距离,由俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。要用最少字符操作将字符串A转换为字符串B。例如将kitten一字转成sitting:(1)sitten(k--->s);(2)sittin(e—>i);(3)sitting(-->g)。

首先定义这样一个函数——d(i, j),它表示第一个字符串的长度为i的子串到第二个字符串的长度为j的子串的编辑距离。显然可以有如下动态规划公式:

1、if i == 0 且 j == 0,d(i, j) = 0

2、if i == 0 且 j > 0,d(i, j) = j

3、if i > 0 且j == 0,d(i, j) = i

4、if i ≥ 1  且 j ≥ 1 ,d(i, j) == min{ d(i-1, j) + 1, d(i, j-1) + 1, d(i-1, j-1) + f(i, j) },当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。这里的d(i-1,j)表示删除第一个字符串的最后一个字符,那么编辑之前问题规模就为d(i-1,j),d(i-1,j-1)表示替换,替换编辑次数为一次,那么问题规模就缩小为d(i-1,j-1),d(i,j-1)表示在第二个字符串后面添加一个字符,表示添加之后与第一个字符串相同,所以编辑之前问题的规模就为d(i,j-1)。

下面是主要代码:

public int getDistance() {
		for (int i = 1; i <= m; i++)
			for (int j = 1; j <= n; j++) {
				if (x.charAt(i - 1) == y.charAt(j - 1))
					d[i][j] = d[i - 1][j - 1];
				else
					d[i][j] = min(d[i][j - 1] + 1, d[i - 1][j] + 1, d[i - 1][j - 1] + 1);
			}
		return d[m][n];
	}
           

这是d数组的初始化函数:

public EditDistance(String x, String y) {
		super();
		this.m = x.length();
		this.n = y.length();
		this.d = new int[m+1][n+1];
		for(int i=0;i<=m;i++){
			d[i][0]=i;
		}
		for(int i=0;i<=n;i++){
			d[0][i]=i;
		}
		this.x = x;
		this.y = y;
	}
           

程序完整代码:http://download.csdn.net/detail/xiyou_android/9238145