EditDistance,求兩個字符串最小編輯距離,動態規划


問題描述:

題目描述
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];
    }
}
 
        

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM