using System; namespace Developpez.Dotnet.Algorithms { /// /// Fournit des méthodes permettant d'évaluer la similarité entre 2 chaînes de caractères, /// selon l'algorithme de la distance de Levenshtein. /// /// L'algorithme de la distance de Levenshtein est décrit ici : /// http://en.wikipedia.org/wiki/Levenshtein_distance. /// public static class Levenshtein { /// /// Calcule la distance de Levenshtein entre 2 chaînes de caractères. /// /// Première chaîne à comparer. /// Seconde chaîne à comparer. /// true pour tenir compte de la casse, false sinon. /// La distance de Levenshtein entre les 2 chaînes. /// /// /// La distance de Levenshtein est toujours supérieure ou égale à la différence de longueur entre les 2 chaines /// La distance de Levenshtein est toujours inférieure ou égale à la longueur de la plus longue chaine /// La distance de Levenshtein entre 2 chaines identiques est 0 /// /// public static int ComputeDistance(string a, string b, bool caseSensitive) { if (!caseSensitive) { a = a.ToLower(); b = b.ToLower(); } int m = a.Length; int n = b.Length; int[,] d = new int[m + 1, n + 1]; for (int i = 0; i <= m; i++) d[i, 0] = i; for (int i = 0; i <= n; i++) d[0, i] = i; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { int cost; if (a[i - 1] == b[j - 1]) cost = 0; else cost = 1; d[i, j] = Min(d[i - 1, j] + 1, d[i, j - 1] + 1, d[i - 1, j - 1] + cost); } } return d[m, n]; } /// /// Calcule le coefficient de corrélation entre 2 chaînes, sur la base de la distance de Levenshtein /// /// Première chaîne à comparer /// Seconde chaîne à comparer /// true pour tenir compte de la casse, false sinon /// Le coefficient de corrélation entre les 2 chaînes. Cette valeur est comprise entre 0 (chaînes complètement différentes) et 1 (chaînes identiques) /// Ce coefficient est calculé selon la formule suivante : 1 - d/L, où d est la distance de Levenshtein entre les 2 chaînes, et L la longueur de la plus longue chaîne. public static double ComputeCorrelation(string a, string b, bool caseSensitive) { int distance = ComputeDistance(a, b, caseSensitive); int longest = Max(a.Length, b.Length); return 1 - (double)distance / longest; } private static T Min(T arg0, params T[] args) where T : IComparable { T min = arg0; for (int i = 0; i < args.Length; i++) { T x = args[i]; if (x.CompareTo(min) < 0) min = x; } return min; } private static T Max(T arg0, params T[] args) where T : IComparable { T max = arg0; for (int i = 0; i < args.Length; i++) { T x = args[i]; if (x.CompareTo(max) > 0) max = x; } return max; } } }