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
思想:利用动态规划的思想求解,distance[i][j]表示word1前i个字符和word2前j个字符所需要的最小编辑次数;而distance[i][j]肯定由distance[i-1][j] 和distance[i][j-1]以及distance[i-1][j-1]转变来的。从而可以得到
distance[i][j] = min { distance[i-1][j] + 1,distance[i][j-1] + 1,distance[i-1][j-1] + (word1[i-2]==word2[j-2]?0:1) }
这里要注意+ 与 == (?:) 之间的优先级,要形成良好的编码习惯,根据思考流程加入括号。
- public int minDistance(String word1, String word2) {
- int wlen1 = word1.length();
- int wlen2 = word2.length();
- int[][] distance = new int[wlen1+1][wlen2+1]; //多申请一个长度
- distance[0][0] = 0;
- for(int i=1;i<=wlen1;i++) {
- distance[i][0] = i;
- }
- for(int i=1;i<=wlen2;i++) {
- distance[0][i] = i;
- }
- for(int i=1;i<=wlen1;i++) {
- for(int j=1;j<=wlen2;j++) {
- int cost = (word1.charAt(i-1) == word2.charAt(j-1) ? 0:1); //注意括号,保证正确优先级
- distance[i][j] = Math.min(distance[i-1][j]+1,Math.min(distance[i][j-1]+1,distance[i-1][j-1]+cost));
- }
- }
- return distance[wlen1][wlen2];
- }
改进:可以backward的思想得到每次的操作,由于可能存在多条路径,可以今选择一条。
代码如下:
- int dp[100][100];
- typedef struct {
- int left;
- int down;
- int slope;
- } Direct;
- Direct direct[100];
- int minimalEditDistance(string s1,string s2) {
- int s1len = s1.size();
- int s2len = s2.size();
- for(int i=1;i<=s2len;i++) {
- dp[0][i] = i;
- }
- for(int i=1;i<=s1len;i++) {
- dp[i][0] = i;
- }
- dp[0][0] = 0;
- for(int i=1;i<=s1len;i++) {
- for(int j=1;j<=s2len;j++) {
- dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1);
- dp[i][j] = min(dp[i][j],dp[i-1][j-1]+(s1[i-1]==s2[j-1]?0:1));
- cout<<i<<'\t'<<j<<'\t'<<dp[i][j]<<endl;
- int cnt=0;
- if(dp[i][j]==dp[i-1][j]+1) {
- direct[i].left = 1;
- } else if(dp[i][j]==dp[i][j-1]) {
- direct[i].down = 1;
- } else {
- direct[i].slope = 1;
- }
- }
- }
- return dp[s1len][s2len];
- }
- int main() {
- //input the string s1 and s2
- string s1 = "abc";
- string s2 = "a";
- memset(direct,0,sizeof(direct));
- cout<< minimalEditDistance(s1,s2) <<endl;
- for(int i=s1.length();i>=1;i--) {
- if(direct[i].left == 1) {
- cout<<"deletion"<<endl;
- } else if(direct[i].down == 1) {
- cout<<"insert"<<endl;
- } else {
- cout<<"substitution"<<endl;
- }
- }
- }

浙公网安备 33010602011771号