在两个弦上找到Levenshtein距离

时间:2017-01-06 22:03:31

标签: java levenshtein-distance

我正在尝试在Eclipse Java Levenshtein distance中使用以下两个字符串实现:

我从维基百科中获取了这个想法,但我不知道为什么输出错误,我需要帮助才能找到我的错误。

  1. “的Kruskal”
  2. “因果”

     package il.ac.oranim.alg2016;
      public class OPT {
     public static void main(String[] args)
    {
    
    char[] t={'k','r','u','s','k','a','l'};
    char[] s={'c','a','u','s','a','l'};
    for (int i=0;i<=s.length;i++)
    {
        for (int j=0;j<=t.length;j++)
        System.out.print(LevenshteinDistance(s,t)[i][j]+" ");
        System.out.println();
    }
     }
    private static int[][] LevenshteinDistance(char s[], char t[])
     {
       // d is a table with m+1 rows and n+1 columns
        int[][] d=new int[s.length+1][t.length+1];    
       for (int i=0;i<=s.length;i++)
         d[i][0] = i; // deletion
       for (int j=0;j<=t.length;j++)
         d[0][j] = j; // insertion
    
       for (int j=1;j<t.length;j++)
       {
         for (int i=1;i<s.length;i++)
         {
           if (s[i] ==t[j]) 
             d[i][j]=d[i-1][j-1];
           else
             d[i][j] = Math.min(Math.min((d[i-1][ j] + 1),
                     (d[i][j-1] + 1)),
                     (d[i-1][j-1] + 1)) ;
         }
       }
    
       return d; 
     }
    

    }

  3. 我的输出:

    0 1 2 3 4 5 6 7 
    1 1 2 3 4 4 5 0 
    2 2 1 2 3 4 5 0 
    3 3 2 1 2 3 4 0 
    4 4 3 2 2 2 3 0 
    5 5 4 3 3 3 2 0 
    6 0 0 0 0 0 0 0 
    

    输出应为:

    0 1 2 3 4 5 6 7 
    1 1 2 3 4 5 6 7 
    2 2 2 3 4 5 5 6 
    3 3 3 2 3 4 5 6 
    4 4 4 3 2 3 4 5 
    5 5 5 4 3 3 3 4 
    6 6 6 5 4 4 4 3 
    

1 个答案:

答案 0 :(得分:4)

如果重新阅读规范,您会发现有两个错误:

  • 在维基百科上,他们使用从1到(包括n)的索引,根据维基百科的i=1,字符串从索引i=0开始Java的;和
  • 权重未正确更新:

    if (s[i] ==t[j]) 
        d[i][j]=d[i-1][j-1];
    

在规范中,这应该是d[i-1][j]+1d[i][j-1]+1d[i-1][j-1]的最小值。我们无法保证d[i-1][j-1]是最低值,因此您应该有效地计算它。

如果考虑到这些错误,可以修改表格更新算法(对评论//进行更改):

for (int j=1;j<=t.length;j++) { //use <= instead of <
    for (int i=1;i<=s.length;i++) { //use <= instead of <
       if (s[i-1] ==t[j-1]) //use i-1 and j-1 
         d[i][j] = Math.min(Math.min(d[i-1][j]+1,d[i][j-1]+1),d[i-1][j-1]); //use the correct update
       else
         d[i][j] = Math.min(Math.min(d[i-1][j]+1,d[i][j-1]+1),d[i-1][j-1]+1);
    }
}