using System; namespace HeuristicLab.Problems.ProgramSynthesis { public static class StringExtensions { public static bool IsNumeric(this string str) { int n; return int.TryParse(str, out n); } /// /// https://github.com/DanHarltey/Fastenshtein /// public static int LevenshteinDistance(this string source, string target) { if (target.Length == 0) { return source.Length; } int[] costs = new int[target.Length]; // Add indexing for insertion to first row for (int i = 0; i < costs.Length;) { costs[i] = ++i; } for (int i = 0; i < source.Length; i++) { // cost of the first index int cost = i; int addationCost = i; // cache value for inner loop to avoid index lookup and bonds checking, profiled this is quicker char value1Char = source[i]; for (int j = 0; j < target.Length; j++) { int insertionCost = cost; cost = addationCost; // assigning this here reduces the array reads we do, improvement of the old version addationCost = costs[j]; if (value1Char != target[j]) { if (insertionCost < cost) { cost = insertionCost; } if (addationCost < cost) { cost = addationCost; } ++cost; } costs[j] = cost; } } return costs[costs.Length - 1]; } /// /// https://www.dotnetperls.com/levenshtein /// public static int LevenshteinDistance2(this string source, string target) { if (source == null && target == null) return 0; if (source == null) return target.Length; if (target == null) return source.Length; int n = source.Length; int m = target.Length; int[,] d = new int[n + 1, m + 1]; // 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 int cost = (target[j - 1] == source[i - 1]) ? 0 : 1; // Step 6 d[i, j] = Math.Min( Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost); } } // Step 7 return d[n, m]; } } }