Source: https://gist.github.com/Davidblkx/e12ab0bb2aff7fd8072632b396538560
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; namespace Plugin.Domain.Helpers { public static class LevenshteinDistance { /// <summary> /// Calculate the difference between 2 strings using the Levenshtein distance algorithm /// </summary> public static int Calculate(string source1, string source2) //O(n*m) { var source1Length = source1.Length; var source2Length = source2.Length; var matrix = new int[source1Length + 1, source2Length + 1]; // First calculation, if one entry is empty return full length if (source1Length == 0) return source2Length; if (source2Length == 0) return source1Length; // Initialization of matrix with row size source1Length and columns size source2Length for (var i = 0; i <= source1Length; matrix[i, 0] = i++) { } for (var j = 0; j <= source2Length; matrix[0, j] = j++) { } // Calculate rows and collumns distances for (var i = 1; i <= source1Length; i++) { for (var j = 1; j <= source2Length; j++) { var cost = (source2[j - 1] == source1[i - 1]) ? 0 : 1; matrix[i, j] = Math.Min( Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1), matrix[i - 1, j - 1] + cost); } } // return result return matrix[source1Length, source2Length]; } public static string RemoveDiacritics(string text) { var normalizedString = text.Normalize(NormalizationForm.FormD); var stringBuilder = new StringBuilder(); foreach (var c in normalizedString) { var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c); if (unicodeCategory != UnicodeCategory.NonSpacingMark) { stringBuilder.Append(c); } } return stringBuilder.ToString().Normalize(NormalizationForm.FormC); } public static Dictionary<string, string> CountryMapping = GetCountryMapping(); public static Dictionary<string, string> GetCountryMapping() { var countryMapping = new Dictionary<string, string>(); var regions = CultureInfo.GetCultures(CultureTypes.AllCultures) .Where(x => !x.Equals(CultureInfo.InvariantCulture)) //Remove the invariant culture as a region cannot be created from it. .Where(x => !x.IsNeutralCulture) //Remove nuetral cultures as a region cannot be created from them. .Select(x => new RegionInfo(x.LCID)); foreach (var regio in regions) { countryMapping[RemoveDiacritics(regio.DisplayName)] = regio.TwoLetterISORegionName; countryMapping[RemoveDiacritics(regio.EnglishName)] = regio.TwoLetterISORegionName; countryMapping[RemoveDiacritics(regio.NativeName)] = regio.TwoLetterISORegionName; } return countryMapping; } public static string ParseCountryWithLevenshtein(string countryName) { var name = RemoveDiacritics(countryName); var result = CountryMapping.Select(x => { return new { Score = Calculate(name, x.Key), Value = x.Value }; }); return result.OrderBy(x => x.Score).Select(x => x.Value).FirstOrDefault(null); } } }
701800cookie-checkC# Levenshtein Distance