using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Protsyk.Toolkit.Levenshtein {
class Program {
static double WeightedLevenshtein(string b1, string b2) {
b1 = b1.ToUpper();
b2 = b2.ToUpper();
double[,] matrix = new double[b1.Length + 1, b2.Length + 1];
for (int i = 1; i <= b1.Length; i++) {
matrix[i, 0] = i;
}
for (int i = 1; i <= b2.Length; i++) {
matrix[0, i] = i;
}
for (int i = 1; i <= b1.Length; i++) {
for (int j = 1; j <= b2.Length; j++) {
double distance_replace = matrix[(i - 1), (j - 1)];
if (b1[i - 1] != b2[j - 1]) {
// Cost of replace
distance_replace += Math.Abs((float)(b1[i - 1]) - b2[j - 1]) / ('Z'-'A');
}
// Cost of remove = 1
double distance_remove = matrix[(i - 1), j] + 1;
// Cost of add = 1
double distance_add = matrix[i, (j - 1)] + 1;
matrix[i, j] = Math.Min(distance_replace,
Math.Min(distance_add, distance_remove));
}
}
return matrix[b1.Length, b2.Length] ;
}
static void Main(string[] args) {
double w1 = WeightedLevenshtein("THEATRE", "TNEATRE");
double w2 = WeightedLevenshtein("THEATRE", "TOEATRE");
Console.WriteLine("Distance between THEATRE and TNEATRE is: " + w1);
Console.WriteLine("Distance between THEATRE and TOEATRE is: " + w2);
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkxpbnE7CnVzaW5nIFN5c3RlbS5UZXh0OwogCm5hbWVzcGFjZSBQcm90c3lrLlRvb2xraXQuTGV2ZW5zaHRlaW4gewogICAgY2xhc3MgUHJvZ3JhbSB7CiAKICAgICAgICBzdGF0aWMgZG91YmxlIFdlaWdodGVkTGV2ZW5zaHRlaW4oc3RyaW5nIGIxLCBzdHJpbmcgYjIpIHsKICAgICAgICAgICAgYjEgPSBiMS5Ub1VwcGVyKCk7CiAgICAgICAgICAgIGIyID0gYjIuVG9VcHBlcigpOwogICAgICAgIAogICAgICAgICAgICBkb3VibGVbLF0gbWF0cml4ID0gbmV3IGRvdWJsZVtiMS5MZW5ndGggKyAxLCBiMi5MZW5ndGggKyAxXTsKIAogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBiMS5MZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgbWF0cml4W2ksIDBdID0gaTsKICAgICAgICAgICAgfQogCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IGIyLkxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBtYXRyaXhbMCwgaV0gPSBpOwogICAgICAgICAgICB9CiAKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gYjEuTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDw9IGIyLkxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZG91YmxlIGRpc3RhbmNlX3JlcGxhY2UgPSBtYXRyaXhbKGkgLSAxKSwgKGogLSAxKV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGIxW2kgLSAxXSAhPSBiMltqIC0gMV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29zdCBvZiByZXBsYWNlCiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlX3JlcGxhY2UgKz0gTWF0aC5BYnMoKGZsb2F0KShiMVtpIC0gMV0pIC0gYjJbaiAtIDFdKSAvICgnWictJ0EnKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIENvc3Qgb2YgcmVtb3ZlID0gMSAKICAgICAgICAgICAgICAgICAgICBkb3VibGUgZGlzdGFuY2VfcmVtb3ZlID0gbWF0cml4WyhpIC0gMSksIGpdICsgMTsKICAgICAgICAgICAgICAgICAgICAvLyBDb3N0IG9mIGFkZCA9IDEKICAgICAgICAgICAgICAgICAgICBkb3VibGUgZGlzdGFuY2VfYWRkID0gbWF0cml4W2ksIChqIC0gMSldICsgMTsKIAogICAgICAgICAgICAgICAgICAgIG1hdHJpeFtpLCBqXSA9IE1hdGguTWluKGRpc3RhbmNlX3JlcGxhY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5NaW4oZGlzdGFuY2VfYWRkLCBkaXN0YW5jZV9yZW1vdmUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogCiAgICAgICAgICAgIHJldHVybiBtYXRyaXhbYjEuTGVuZ3RoLCBiMi5MZW5ndGhdIDsKICAgICAgICB9CiAKICAgICAgICBzdGF0aWMgdm9pZCBNYWluKHN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICAgICAgZG91YmxlIHcxID0gV2VpZ2h0ZWRMZXZlbnNodGVpbigiVEhFQVRSRSIsICJUTkVBVFJFIik7CiAgICAgICAgICAgIGRvdWJsZSB3MiA9IFdlaWdodGVkTGV2ZW5zaHRlaW4oIlRIRUFUUkUiLCAiVE9FQVRSRSIpOwogCiAgICAgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKCJEaXN0YW5jZSBiZXR3ZWVuIFRIRUFUUkUgYW5kIFRORUFUUkUgaXM6ICIgKyB3MSk7CiAgICAgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKCJEaXN0YW5jZSBiZXR3ZWVuIFRIRUFUUkUgYW5kIFRPRUFUUkUgaXM6ICIgKyB3Mik7CiAgICAgICAgfQogICAgfQp9