#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// Change these strings to test the program
#define STRING_X "SUNDAY"
#define STRING_Y "SATURDAY"
#define SENTINEL (-1)
#define INSERT_COST (1)
#define DELETE_COST (1)
#define REPLACE_COST (1)
inline
int min(int a, int b) {
return a < b ? a : b;
}
// Returns Minimum among a, b, c
int Minimum(int a, int b, int c)
{
return min(min(a, b), c);
}
// Strings of size m and n are passed.
// Construct the Table for X[0...m, m+1], Y[0...n, n+1]
int EditDistanceDP(char X[], char Y[])
{
// Cost of alignment
int cost = 0;
int leftCell, topCell, cornerCell;
int m = strlen(X)+1;
int n = strlen(Y)+1;
// T[m][n]
int *T = (int *)malloc(m * n * sizeof(int));
// Initialize table
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
*(T + i * n + j) = SENTINEL;
// Set up base cases
// T[i][0] = i
for(int i = 0; i < m; i++)
*(T + i * n) = i;
// T[0][j] = j
for(int j = 0; j < n; j++)
*(T + j) = j;
// Build the T in top-down fashion
for(int i = 1; i < m; i++)
{
for(int j = 1; j < n; j++)
{
// T[i][j-1]
leftCell = *(T + i*n + j-1);
leftCell += DELETE_COST; // deletion
// T[i-1][j]
topCell = *(T + (i-1)*n + j);
topCell += INSERT_COST; // insertion
// Top-left (corner) cell
// T[i-1][j-1]
cornerCell = *(T + (i-1)*n + (j-1) );
// edit[(i-1), (j-1)] = 0 if X[i] == Y[j], 1 otherwise
cornerCell += REPLACE_COST * (X[i-1] != Y[j-1]); // may be replace
// Minimum cost of current cell
// Fill in the next cell T[i][j]
*(T + (i)*n + (j)) = Minimum(leftCell, topCell, cornerCell);
}
}
// Cost is in the cell T[m][n]
cost = *(T + m*n - 1);
free(T);
return cost;
}
// Recursive implementation
int EditDistanceRecursion( char *X, char *Y, int m, int n )
{
// Base cases
if( m == 0 && n == 0 )
return 0;
if( m == 0 )
return n;
if( n == 0 )
return m;
// Recurse
int left = EditDistanceRecursion(X, Y, m-1, n) + 1;
int right = EditDistanceRecursion(X, Y, m, n-1) + 1;
int corner = EditDistanceRecursion(X, Y, m-1, n-1) + (X[m-1] != Y[n-1]);
return Minimum(left, right, corner);
}
int main()
{
char X[] = STRING_X; // vertical
char Y[] = STRING_Y; // horizontal
printf("Minimum edits required to convert %s into %s is %d\n",
X, Y, EditDistanceDP(X, Y) );
printf("Minimum edits required to convert %s into %s is %d by recursion\n",
X, Y, EditDistanceRecursion(X, Y, strlen(X), strlen(Y)));
return 0;
}
I2luY2x1ZGU8c3RkaW8uaD4KI2luY2x1ZGU8c3RkbGliLmg+CiNpbmNsdWRlPHN0cmluZy5oPgogCi8vIENoYW5nZSB0aGVzZSBzdHJpbmdzIHRvIHRlc3QgdGhlIHByb2dyYW0KI2RlZmluZSBTVFJJTkdfWCAiU1VOREFZIgojZGVmaW5lIFNUUklOR19ZICJTQVRVUkRBWSIKIAojZGVmaW5lIFNFTlRJTkVMICgtMSkKI2RlZmluZSBJTlNFUlRfQ09TVCAoMSkKI2RlZmluZSBERUxFVEVfQ09TVCAoMSkKI2RlZmluZSBSRVBMQUNFX0NPU1QgKDEpCiAKaW5saW5lCmludCBtaW4oaW50IGEsIGludCBiKSB7CiAgIHJldHVybiBhIDwgYiA/IGEgOiBiOwp9CiAKLy8gUmV0dXJucyBNaW5pbXVtIGFtb25nIGEsIGIsIGMKaW50IE1pbmltdW0oaW50IGEsIGludCBiLCBpbnQgYykKewogICAgcmV0dXJuIG1pbihtaW4oYSwgYiksIGMpOwp9CiAKLy8gU3RyaW5ncyBvZiBzaXplIG0gYW5kIG4gYXJlIHBhc3NlZC4KLy8gQ29uc3RydWN0IHRoZSBUYWJsZSBmb3IgWFswLi4ubSwgbSsxXSwgWVswLi4ubiwgbisxXQppbnQgRWRpdERpc3RhbmNlRFAoY2hhciBYW10sIGNoYXIgWVtdKQp7CiAgICAvLyBDb3N0IG9mIGFsaWdubWVudAogICAgaW50IGNvc3QgPSAwOwogICAgaW50IGxlZnRDZWxsLCB0b3BDZWxsLCBjb3JuZXJDZWxsOwogCiAgICBpbnQgbSA9IHN0cmxlbihYKSsxOwogICAgaW50IG4gPSBzdHJsZW4oWSkrMTsKIAogICAgLy8gVFttXVtuXQogICAgaW50ICpUID0gKGludCAqKW1hbGxvYyhtICogbiAqIHNpemVvZihpbnQpKTsKIAogICAgLy8gSW5pdGlhbGl6ZSB0YWJsZQogICAgZm9yKGludCBpID0gMDsgaSA8IG07IGkrKykKICAgICAgICBmb3IoaW50IGogPSAwOyBqIDwgbjsgaisrKQogICAgICAgICAgICAqKFQgKyBpICogbiArIGopID0gU0VOVElORUw7CiAKICAgIC8vIFNldCB1cCBiYXNlIGNhc2VzCiAgICAvLyBUW2ldWzBdID0gaQogICAgZm9yKGludCBpID0gMDsgaSA8IG07IGkrKykKICAgICAgICAqKFQgKyBpICogbikgPSBpOwogCiAgICAvLyBUWzBdW2pdID0gagogICAgZm9yKGludCBqID0gMDsgaiA8IG47IGorKykKICAgICAgICAqKFQgKyBqKSA9IGo7CiAKICAgIC8vIEJ1aWxkIHRoZSBUIGluIHRvcC1kb3duIGZhc2hpb24KICAgIGZvcihpbnQgaSA9IDE7IGkgPCBtOyBpKyspCiAgICB7CiAgICAgICAgZm9yKGludCBqID0gMTsgaiA8IG47IGorKykKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRbaV1bai0xXQogICAgICAgICAgICBsZWZ0Q2VsbCA9ICooVCArIGkqbiArIGotMSk7CiAgICAgICAgICAgIGxlZnRDZWxsICs9IERFTEVURV9DT1NUOyAvLyBkZWxldGlvbgogCiAgICAgICAgICAgIC8vIFRbaS0xXVtqXQogICAgICAgICAgICB0b3BDZWxsID0gKihUICsgKGktMSkqbiArIGopOwogICAgICAgICAgICB0b3BDZWxsICs9IElOU0VSVF9DT1NUOyAvLyBpbnNlcnRpb24KIAogICAgICAgICAgICAvLyBUb3AtbGVmdCAoY29ybmVyKSBjZWxsCiAgICAgICAgICAgIC8vIFRbaS0xXVtqLTFdCiAgICAgICAgICAgIGNvcm5lckNlbGwgPSAqKFQgKyAoaS0xKSpuICsgKGotMSkgKTsKIAogICAgICAgICAgICAvLyBlZGl0WyhpLTEpLCAoai0xKV0gPSAwIGlmIFhbaV0gPT0gWVtqXSwgMSBvdGhlcndpc2UKICAgICAgICAgICAgY29ybmVyQ2VsbCArPSBSRVBMQUNFX0NPU1QgKiAoWFtpLTFdICE9IFlbai0xXSk7IC8vIG1heSBiZSByZXBsYWNlCiAKICAgICAgICAgICAgLy8gTWluaW11bSBjb3N0IG9mIGN1cnJlbnQgY2VsbAogICAgICAgICAgICAvLyBGaWxsIGluIHRoZSBuZXh0IGNlbGwgVFtpXVtqXQogICAgICAgICAgICAqKFQgKyAoaSkqbiArIChqKSkgPSBNaW5pbXVtKGxlZnRDZWxsLCB0b3BDZWxsLCBjb3JuZXJDZWxsKTsKICAgICAgICB9CiAgICB9CiAKICAgIC8vIENvc3QgaXMgaW4gdGhlIGNlbGwgVFttXVtuXQogICAgY29zdCA9ICooVCArIG0qbiAtIDEpOwogICAgZnJlZShUKTsKICAgIHJldHVybiBjb3N0Owp9CiAKLy8gUmVjdXJzaXZlIGltcGxlbWVudGF0aW9uCmludCBFZGl0RGlzdGFuY2VSZWN1cnNpb24oIGNoYXIgKlgsIGNoYXIgKlksIGludCBtLCBpbnQgbiApCnsKICAgIC8vIEJhc2UgY2FzZXMKICAgIGlmKCBtID09IDAgJiYgbiA9PSAwICkKICAgICAgICByZXR1cm4gMDsKIAogICAgaWYoIG0gPT0gMCApCiAgICAgICAgcmV0dXJuIG47CiAKICAgIGlmKCBuID09IDAgKQogICAgICAgIHJldHVybiBtOwogCiAgICAvLyBSZWN1cnNlCiAgICBpbnQgbGVmdCA9IEVkaXREaXN0YW5jZVJlY3Vyc2lvbihYLCBZLCBtLTEsIG4pICsgMTsKICAgIGludCByaWdodCA9IEVkaXREaXN0YW5jZVJlY3Vyc2lvbihYLCBZLCBtLCBuLTEpICsgMTsKICAgIGludCBjb3JuZXIgPSBFZGl0RGlzdGFuY2VSZWN1cnNpb24oWCwgWSwgbS0xLCBuLTEpICsgKFhbbS0xXSAhPSBZW24tMV0pOwogCiAgICByZXR1cm4gTWluaW11bShsZWZ0LCByaWdodCwgY29ybmVyKTsKfQogCmludCBtYWluKCkKewogICAgY2hhciBYW10gPSBTVFJJTkdfWDsgLy8gdmVydGljYWwKICAgIGNoYXIgWVtdID0gU1RSSU5HX1k7IC8vIGhvcml6b250YWwKIAogICAgcHJpbnRmKCJNaW5pbXVtIGVkaXRzIHJlcXVpcmVkIHRvIGNvbnZlcnQgJXMgaW50byAlcyBpcyAlZFxuIiwKICAgICAgICAgICBYLCBZLCBFZGl0RGlzdGFuY2VEUChYLCBZKSApOwogICAgcHJpbnRmKCJNaW5pbXVtIGVkaXRzIHJlcXVpcmVkIHRvIGNvbnZlcnQgJXMgaW50byAlcyBpcyAlZCBieSByZWN1cnNpb25cbiIsCiAgICAgICAgICAgWCwgWSwgRWRpdERpc3RhbmNlUmVjdXJzaW9uKFgsIFksIHN0cmxlbihYKSwgc3RybGVuKFkpKSk7CiAKICAgIHJldHVybiAwOwp9