天天看點

最小編輯距離(字元串相似度)

編輯距離問題:又稱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