3-5 编辑距离问题
   
    问题描述
   
    设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:
    
    (1)删除一个字符;
    
    (2)插入一个字符;
    
    (3)将一个字符改为另一个字符。
   
将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。
    输入:第1行是字符串A,第2行是字符串B。
    
    输出:字符串A和B的编辑距离d(A,B)
   
    分析
   
    设所给的2个字符串为A[1…m]和B[1…n]。定义D[i, j]=
    
    
     
      
       
        
         
          δ
         
        
        
        
       
      
      
     
     
      δ
     
    
    
    (A[1…i], B[1…j])。单字符a,b间的距离定义为
    
    
    
     
      
       
        
         
          δ
         
        
        
        
       
      
      
     
     
      δ
     
    
    
    (a, b) = 0 当a = b;
    
    
    
     
      
       
        
         
          δ
         
        
        
        
       
      
      
     
     
      δ
     
    
    
    (a, b) = 1 当a != b;
    
    考察从字符串A[1…i]到字符串B[1…j]的变换。可分以下几种情况来讨论。
   
- 
     字符A[i]改为字符B[j];需要
 
 
 
 
 
 
 
 δ
 
 
 
 
 
 
 
 
 
 δ
 
 
 
 (A[i], B[j])次操作。
- 删除字符A[i];需要1次操作。
- 插入字符B[j];需要1次操作。
    因此,D[i, j]可递归地计算如下:
    
    D[i, j] = min{ D[i-1, j-1]+
    
    
     
      
       
        
         
          δ
         
        
        
        
       
      
      
     
     
      δ
     
    
    
    (A[i], B[j]), D[i-1, j]+1, D[i, j-1]+1}
   
    D[i, j]的初始值为:
    
    D[i, 0] = i, 0<=i<=m
    
    D[0, j] = j, 0<=j<=n
   
    Java: version 1
   
import java.util.Scanner;
public class BianJiJuLi {
    public static void main(String[] args){
        String A, B;
        int lenA, lenB;
        char[] tmpA, tmpB;
        char[] arrA, arrB;
        int[][] D;
        int i, j;
        int MAX = 100000;
        int delta;
        Scanner input = new Scanner(System.in);
        while (true){
            A = input.next();//fxpimu
            B = input.next();//xwrs
            lenA = A.length();
            lenB = B.length();
            D = new int[lenA+1][lenB+1];
            tmpA = A.toCharArray();
            tmpB = B.toCharArray();
            arrA = new char[lenA+1];
            arrB = new char[lenB+1];
            System.arraycopy(tmpA, 0, arrA, 1, lenA);
            System.arraycopy(tmpB, 0, arrB, 1, lenB);
            for(i=1; i<=lenA; i++)
                D[i][0] = i;
            for(j=1; j<=lenB; j++)
                D[0][j] = j;
            for(i=1; i<=lenA; i++)
                for(j=1; j<=lenB; j++){
                    D[i][j] = MAX;
                    if(arrA[i] == arrB[j])
                        delta = 0;
                    else
                        delta = 1;
                    if(D[i][j] > D[i-1][j-1]+delta)
                        D[i][j] = D[i-1][j-1]+delta;
                    if(D[i][j] > D[i-1][j]+1)
                        D[i][j] = D[i-1][j]+1;
                    if(D[i][j] > D[i][j-1]+1)
                        D[i][j] = D[i][j-1]+1;
                }
             System.out.println(D[lenA][lenB]);
        }
    }
}
或
import java.util.Scanner;
public class BianJiJuLi {
    public static void main(String[] args){
        String A, B;
        int lenA, lenB;
        char[] tmpA, tmpB;
//        char[] arrA, arrB;
        int[][] D;
        int i, j;
        int MAX = 100000;
        int delta;
        Scanner input = new Scanner(System.in);
        while (true){
            A = input.next();//fxpimu
            B = input.next();//xwrs
            lenA = A.length();
            lenB = B.length();
            D = new int[lenA+1][lenB+1];
            tmpA = A.toCharArray();
            tmpB = B.toCharArray();
//            arrA = new char[lenA+1];
//            arrB = new char[lenB+1];
//            System.arraycopy(tmpA, 0, arrA, 1, lenA);
//            System.arraycopy(tmpB, 0, arrB, 1, lenB);
            for(i=1; i<=lenA; i++)
                D[i][0] = i;
            for(j=1; j<=lenB; j++)
                D[0][j] = j;
            for(i=1; i<=lenA; i++)
                for(j=1; j<=lenB; j++){
                    D[i][j] = MAX;
                    if(tmpA[i-1] == tmpB[j-1])
//                    if(arrA[i] == arrB[j])
                        delta = 0;
                    else
                        delta = 1;
                    if(D[i][j] > D[i-1][j-1]+delta)
                        D[i][j] = D[i-1][j-1]+delta;
                    if(D[i][j] > D[i-1][j]+1)
                        D[i][j] = D[i-1][j]+1;
                    if(D[i][j] > D[i][j-1]+1)
                        D[i][j] = D[i][j-1]+1;
                }
             System.out.println(D[lenA][lenB]);
        }
    }
}
    Input & Output
   
fxpimu
xwrs
5
fxpimu
fxpimu
0
fxpimu
f
5
fxpimu
mu
4
fxpimu
u
5
fxpimu
q
6
    Java: version 2
   
import java.util.Scanner;
public class BianJiJuLi1 {
    public static void main(String[] args){
        String A, B;
        int lenA, lenB;
        char[] arrA, arrB;
        int[] D;
        int i, j;
        int MAX = 100000;
        int delta;
        int x, y, z;
        Scanner input = new Scanner(System.in);
        while (true){
            A = input.next();//fxpimu
            B = input.next();//xwrs
            lenA = A.length();
            lenB = B.length();
            D = new int[lenB+1];
            arrA = A.toCharArray();
            arrB = B.toCharArray();
            for(j=1; j<=lenB; j++)
                D[j] = j;
            for(i=1; i<=lenA; i++){
                y = i-1;
                for(j=1; j<=lenB; j++){
                    x = y;
                    y = D[j];
                    D[j] = MAX;
                    z = j>1?D[j-1]:i;
                    if(arrA[i-1] == arrB[j-1])
                        delta = 0;
                    else
                        delta = 1;
                    if(D[j] > (x+delta))
                        D[j] = x+delta;
                    if(D[j] > (y+1))
                        D[j] = y+1;
                    if(D[j] > z+1)
                        D[j] = z+1;
                }
            }
            System.out.println(D[lenB]);
        }
    }
}
    Input & Output
   
fxpimu
fxpimu
0
fxpimu
xwrs
5
fxpimu
f
5
fxpimu
im
4
fxpimu
iq
5
    Reference
   
王晓东《计算机算法设计与分析》(第3版)P89-90
 
