喜欢多维的锯齿状阵列

时间:2014-09-15 16:09:58

标签: c# multidimensional-array jagged-arrays

我从visual studio(Prefer jagged arrays over multidimensional)得到了这个性能问题 要替换的代码是" //矩阵"。
我怎么能用我的代码做到这一点?

      public static int LevenshteinDistance(string s, string t)
    {
        int n = s.Length; //length of s
        int m = t.Length; //length of t

        int[,] d = new int[n + 1, m + 1]; // matrix

        int cost; // cost
        // Step 1
        if (n == 0) return m;
        if (m == 0) return n;
        // Step 2
        for (int i = 0; i <= n; d[i, 0] = i++) ;
        for (int j = 0; j <= m; d[0, j] = j++) ;
        // Step 3
        for (int i = 1; i <= n; i++)
        {
            //Step 4
            for (int j = 1; j <= m; j++)
            {
                // Step 5
                cost = (t.Substring(j - 1, 1) == s.Substring(i - 1, 1) ? 0 : 1);
                // Step 6
                d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
                          d[i - 1, j - 1] + cost);
            }
        }
        // Step 7
        return d[n, m];
    }

1 个答案:

答案 0 :(得分:2)

这是一个只使用单维数组的版本。

public static int LevenshteinDistance(string s, string t)
{
    int n = s.Length; //length of s
    int m = t.Length; //length of t

    int stride = m+1;
    int[] d = new int[(n + 1)*stride];
    // note, d[i*m + i + j] holds (i,j)

    int cost;
    // Step 1
    if (n == 0) return m;
    if (m == 0) return n;
    // Step 2, adjusted to skip (0,0)
    for (int i = 0, k = stride; k < d.Length; k += stride) d[k] = ++i;
    for (int j = 1; j < stride; ++j) d[j] = j;
    // Step 3
    int newrow = stride * 2;
    char si = s[0];
    for (int i=0, j=0, k = stride + 1; k < d.Length; ++k)
    {
        // don't overwrite d[i,0]
        if (k == newrow) {
            newrow += stride;
            j=0;
            si=s[++i];
            continue;
        }

        // Step 5
        cost = (t[j] == si ? 0 : 1);

        // Step 6
        d[k] = System.Math.Min(System.Math.Min(
             d[k-stride] + 1, /* up one row */
             d[k-1] + 1       /* left one */   ),
             d[k-stride-1] + cost /* diagonal */ );
    }

    // Step 7
    return d[d.Length-1];
}

这应该以3种方式提高绩效:

  • 没有字符串比较,也没有用于清理GC的单字符字符串垃圾
  • 更改内存布局以匹配迭代顺序,改善缓存行为
  • 使用单维数组和优化程序友好的习语,这应该减少边界检查

但是,我很确定应用mike z建议使用两个向量将使代码更清晰。