Edit distance recursive algorithm — Skiena

后端 未结 6 1743
执笔经年
执笔经年 2020-12-30 02:37

I\'m reading The Algorithm Design Manual by Steven Skiena, and I\'m on the dynamic programming chapter. He has some example code for edit distance and uses some functions w

6条回答
  •  醉梦人生
    2020-12-30 03:03

    This is a recursive algorithm not dynamic programming. Note that both i & j point to the last char of s & t respectively when the algorithm starts.

    indel returns 1. match(a, b) returns 0 if a = b (match) else return 1 (substitution)

    #define MATCH     0       /* enumerated type symbol for match */
    #define INSERT    1       /* enumerated type symbol for insert */
    #define DELETE    2       /* enumerated type symbol for delete */
    
    int string_compare(char *s, char *t, int i, int j)
    {
        int k;                  /* counter */
        int opt[3];             /* cost of the three options */
        int lowest_cost;        /* lowest cost */
    
        // base case, if i is 0, then we reached start of s and 
        // now it's empty, so there would be j * 1 edit distance between s & t
        // think of it if s is initially empty and t is not, how many
        // edits we need to perform on s to be similar to t? answer is where
        // we are at t right now which is j
        if (i == 0) return(j * indel(' '));
        // same reasoning as above but for s instead of t
        if (j == 0) return(i * indel(' '));
    
        // calculate opt[match] by checking if s[i] = t[j] which = 0 if true or 1 if not
        // then recursively do the same for s[i-1] & t[j-1]
        opt[MATCH] = string_compare(s,t,i-1,j-1) + match(s[i],t[j]);
        // calculate opt[insert] which is how many chars we need to insert 
        // in s to make it looks like t, or look at it from the other way,
        // how many chars we need to delete from t to make it similar to s?
        // since we're deleting from t, we decrease j by 1 and leave i (pointer
        // in s) as is + indel(t[j]) which we deleted (always returns 1)
        opt[INSERT] = string_compare(s,t,i,j-1) + indel(t[j]);
        // same reasoning as before but deleting from s or inserting into t
        opt[DELETE] = string_compare(s,t,i-1,j) + indel(s[i]);
    
        // these lines are just to pick the min of opt[match], opt[insert], and
        // opt[delete]
        lowest_cost = opt[MATCH];
        for (k=INSERT; k<=DELETE; k++)
                if (opt[k] < lowest_cost) lowest_cost = opt[k];
    
        return( lowest_cost );
    }
    

    The algorithm is not hard to understand, you just need to read it couple of times. What's always amuse me is the person who invented it and the trust that recursion will do the right thing.

提交回复
热议问题