{"id":7018,"date":"2022-11-21T10:03:46","date_gmt":"2022-11-21T09:03:46","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=7018"},"modified":"2022-11-21T10:50:05","modified_gmt":"2022-11-21T09:50:05","slug":"c-levenshtein-distance","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-levenshtein-distance\/","title":{"rendered":"C# Levenshtein Distance"},"content":{"rendered":"\n<p>Source: <a href=\"https:\/\/gist.github.com\/Davidblkx\/e12ab0bb2aff7fd8072632b396538560\">https:\/\/gist.github.com\/Davidblkx\/e12ab0bb2aff7fd8072632b396538560<\/a><\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"csharp\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">using System;\r\nusing System.Collections.Generic;\r\nusing System.Globalization;\r\nusing System.Linq;\r\nusing System.Text;\r\n\r\nnamespace Plugin.Domain.Helpers\r\n{\r\n    public static class LevenshteinDistance\r\n    {\r\n        \/\/\/ &lt;summary>\r\n        \/\/\/ Calculate the difference between 2 strings using the Levenshtein distance algorithm\r\n        \/\/\/ &lt;\/summary>\r\n        public static int Calculate(string source1, string source2) \/\/O(n*m)\r\n        {\r\n            var source1Length = source1.Length;\r\n            var source2Length = source2.Length;\r\n\r\n            var matrix = new int[source1Length + 1, source2Length + 1];\r\n\r\n            \/\/ First calculation, if one entry is empty return full length\r\n            if (source1Length == 0) return source2Length;\r\n            if (source2Length == 0) return source1Length;\r\n\r\n            \/\/ Initialization of matrix with row size source1Length and columns size source2Length\r\n            for (var i = 0; i &lt;= source1Length; matrix[i, 0] = i++) { }\r\n            for (var j = 0; j &lt;= source2Length; matrix[0, j] = j++) { }\r\n\r\n            \/\/ Calculate rows and collumns distances\r\n            for (var i = 1; i &lt;= source1Length; i++)\r\n            {\r\n                for (var j = 1; j &lt;= source2Length; j++)\r\n                {\r\n                    var cost = (source2[j - 1] == source1[i - 1]) ? 0 : 1;\r\n\r\n                    matrix[i, j] = Math.Min(\r\n                        Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1),\r\n                        matrix[i - 1, j - 1] + cost);\r\n                }\r\n            }\r\n            \/\/ return result\r\n            return matrix[source1Length, source2Length];\r\n        }\r\n\r\n        public static string RemoveDiacritics(string text)\r\n        {\r\n            var normalizedString = text.Normalize(NormalizationForm.FormD);\r\n            var stringBuilder = new StringBuilder();\r\n            foreach (var c in normalizedString)\r\n            {\r\n                var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);\r\n                if (unicodeCategory != UnicodeCategory.NonSpacingMark)\r\n                {\r\n                    stringBuilder.Append(c);\r\n                }\r\n            }\r\n            return stringBuilder.ToString().Normalize(NormalizationForm.FormC);\r\n        }\r\n\r\n        public static Dictionary&lt;string, string> CountryMapping = GetCountryMapping();\r\n\r\n        public static Dictionary&lt;string, string> GetCountryMapping()\r\n        {\r\n            var countryMapping = new Dictionary&lt;string, string>();\r\n            var regions = CultureInfo.GetCultures(CultureTypes.AllCultures)\r\n                .Where(x => !x.Equals(CultureInfo.InvariantCulture)) \/\/Remove the invariant culture as a region cannot be created from it.\r\n                .Where(x => !x.IsNeutralCulture) \/\/Remove nuetral cultures as a region cannot be created from them.\r\n                .Select(x => new RegionInfo(x.LCID));\r\n            foreach (var regio in regions)\r\n            {\r\n                countryMapping[RemoveDiacritics(regio.DisplayName)] = regio.TwoLetterISORegionName;\r\n                countryMapping[RemoveDiacritics(regio.EnglishName)] = regio.TwoLetterISORegionName;\r\n                countryMapping[RemoveDiacritics(regio.NativeName)] = regio.TwoLetterISORegionName;\r\n            }\r\n            return countryMapping;\r\n        }\r\n\r\n        public static string ParseCountryWithLevenshtein(string countryName)\r\n        {\r\n            var name = RemoveDiacritics(countryName);\r\n            var result = CountryMapping.Select(x => {\r\n                return new\r\n                {\r\n                    Score = Calculate(name, x.Key),\r\n                    Value = x.Value\r\n                };\r\n            });\r\n            return result.OrderBy(x => x.Score).Select(x => x.Value).FirstOrDefault(null);\r\n        }\r\n    }\r\n}\r\n<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/gist.github.com\/Davidblkx\/e12ab0bb2aff7fd8072632b396538560<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7018","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=7018"}],"version-history":[{"count":4,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7018\/revisions"}],"predecessor-version":[{"id":7024,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7018\/revisions\/7024"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=7018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=7018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=7018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}