MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Globalization;6 7namespace System.Management.Automation8{9 internal class FuzzyMatcher10 {11 internal readonly uint MinimumDistance;12 13 internal FuzzyMatcher(uint minimumDistance)14 {15 MinimumDistance = minimumDistance;16 }17 18 /// <summary>19 /// Determine if the two strings are considered similar.20 /// </summary>21 internal bool IsFuzzyMatch(string candidate, string pattern)22 {23 return IsFuzzyMatch(candidate, pattern, out _);24 }25 26 /// <summary>27 /// Determine if the two strings are considered similar, and return the similarity score.28 /// </summary>29 /// <param name="candidate">The candidate string to be compared.</param>30 /// <param name="pattern">The pattern string to be compared with.</param>31 /// <returns>True if the two strings have a distance <= MinimumDistance.</returns>32 internal bool IsFuzzyMatch(string candidate, string pattern, out int score)33 {34 score = GetDamerauLevenshteinDistance(candidate, pattern);35 return score <= MinimumDistance;36 }37 38 /// <summary>39 /// Compute the case-insensitive distance between two strings.40 /// Based off https://www.csharpstar.com/csharp-string-distance-algorithm/.41 /// </summary>42 /// <param name="string1">The first string to compare.</param>43 /// <param name="string2">The second string to compare.</param>44 /// <returns>The distance value where the lower the value the shorter the distance between the two strings representing a closer match.</returns>45 internal static int GetDamerauLevenshteinDistance(string string1, string string2)46 {47 string1 = string1.ToUpper(CultureInfo.CurrentCulture);48 string2 = string2.ToUpper(CultureInfo.CurrentCulture);49 50 var bounds = new { Height = string1.Length + 1, Width = string2.Length + 1 };51 52 int[,] matrix = new int[bounds.Height, bounds.Width];53 54 for (int height = 0; height < bounds.Height; height++)55 {56 matrix[height, 0] = height;57 }58 59 for (int width = 0; width < bounds.Width; width++)60 {61 matrix[0, width] = width;62 }63 64 for (int height = 1; height < bounds.Height; height++)65 {66 for (int width = 1; width < bounds.Width; width++)67 {68 int cost = (string1[height - 1] == string2[width - 1]) ? 0 : 1;69 int insertion = matrix[height, width - 1] + 1;70 int deletion = matrix[height - 1, width] + 1;71 int substitution = matrix[height - 1, width - 1] + cost;72 73 int distance = Math.Min(insertion, Math.Min(deletion, substitution));74 75 if (height > 1 && width > 1 && string1[height - 1] == string2[width - 2] && string1[height - 2] == string2[width - 1])76 {77 distance = Math.Min(distance, matrix[height - 2, width - 2] + cost);78 }79 80 matrix[height, width] = distance;81 }82 }83 84 return matrix[bounds.Height - 1, bounds.Width - 1];85 }86 }87}88 