Advertisement
Guest User

Untitled

a guest
Nov 21st, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.85 KB | None | 0 0
  1. const double ThresholdSentence = 0.25;
  2. const double ThresholdWord = 0.45;
  3. const int SubtokenLength = 2;
  4. const int MinWordLength = 3;
  5. /// <summary>
  6. /// Приводит предложение к нормальному виду:
  7. /// - в нижнем регистре
  8. /// - удалены не буквы и не цифры
  9. /// </summary>
  10. /// <param name="sentence">Предложение.</param>
  11. /// <returns>Нормализованное предложение.</returns>
  12. private string NormalizeSentence(string sentence)
  13. {
  14.     var resultContainer = new StringBuilder(100);
  15.     var lowerSentece = sentence.ToLower();
  16.     foreach (var c in lowerSentece)
  17.     {
  18.         if (IsNormalChar(c))
  19.         {
  20.             resultContainer.Append(c);
  21.         }
  22.     }
  23.  
  24.     return resultContainer.ToString();
  25. }
  26.  
  27. /// <summary>
  28. /// Возвращает признак подходящего символа.
  29. /// </summary>
  30. /// <param name="c">Символ.</param>
  31. /// <returns>True - если символ буква или цифра или пробел, False - иначе.</returns>
  32. private bool IsNormalChar(char c)
  33. {
  34.     return char.IsLetterOrDigit(c) || c == ' ';
  35. }
  36.  
  37. /// <summary>
  38. /// Разбивает предложение на слова.
  39. /// </summary>
  40. /// <param name="sentence">Предложение.</param>
  41. /// <returns>Набор слов.</returns>
  42. private string[] GetTokens(string sentence)
  43. {
  44.     var tokens = new List<string>();
  45.     var words = sentence.Split(' ');
  46.     foreach (var word in words)
  47.     {
  48.         if (word.Length >= MinWordLength)
  49.         {
  50.             tokens.Add(word);
  51.         }
  52.     }
  53.  
  54.     return tokens.ToArray();
  55. }
  56.  
  57. /// <summary>
  58. /// Возвращает результат нечеткого сравнения слов.
  59. /// </summary>
  60. /// <param name="firstToken">Первое слово.</param>
  61. /// <param name="secondToken">Второе слово.</param>
  62. /// <returns>Результат нечеткого сравения слов.</returns>
  63. private bool IsTokensFuzzyEqual(string firstToken, string secondToken)
  64. {
  65.     var equalSubtokensCount = 0;
  66.     var usedTokens = new bool[secondToken.Length - SubtokenLength + 1];
  67.     for (var i = 0; i < firstToken.Length - SubtokenLength + 1; ++i)
  68.     {
  69.         var subtokenFirst = firstToken.Substring(i, SubtokenLength);
  70.         for (var j = 0; j < secondToken.Length - SubtokenLength + 1; ++j)
  71.         {
  72.             if (!usedTokens[j])
  73.             {
  74.                 var subtokenSecond = secondToken.Substring(j, SubtokenLength);
  75.                 if (subtokenFirst.Equals(subtokenSecond))
  76.                 {
  77.                     equalSubtokensCount++;
  78.                     usedTokens[j] = true;
  79.                     break;
  80.                 }
  81.             }
  82.         }
  83.     }
  84.  
  85.     var subtokenFirstCount = firstToken.Length - SubtokenLength + 1;
  86.     var subtokenSecondCount = secondToken.Length - SubtokenLength + 1;
  87.  
  88.     var tanimoto = (1.0 * equalSubtokensCount) / (subtokenFirstCount + subtokenSecondCount - equalSubtokensCount);
  89.  
  90.     return ThresholdWord <= tanimoto;
  91. }
  92.  
  93. /// <summary>
  94. /// Вычисляет значение нечеткого сравнения предложений.
  95. /// </summary>
  96. /// <param name="first">Первое предложение.</param>
  97. /// <param name="second">Второе предложение.</param>
  98. /// <returns>Результат нечеткого сравнения предложений.</returns>
  99. public double CalculateFuzzyEqualValue(string first, string second)
  100. {
  101.     if (string.IsNullOrWhiteSpace(first) && string.IsNullOrWhiteSpace(second))
  102.     {
  103.         return 1.0;
  104.     }
  105.  
  106.     if (string.IsNullOrWhiteSpace(first) || string.IsNullOrWhiteSpace(second))
  107.     {
  108.         return 0.0;
  109.     }
  110.  
  111.     var normalizedFirst = NormalizeSentence(first);
  112.     var normalizedSecond = NormalizeSentence(second);
  113.  
  114.     var tokensFirst = GetTokens(normalizedFirst);
  115.     var tokensSecond = GetTokens(normalizedSecond);
  116.  
  117.     var fuzzyEqualsTokens = GetFuzzyEqualsTokens(tokensFirst, tokensSecond);
  118.  
  119.     var equalsCount = fuzzyEqualsTokens.Length;
  120.     var firstCount = tokensFirst.Length;
  121.     var secondCount = tokensSecond.Length;
  122.  
  123.     var resultValue = (1.0 * equalsCount) / (firstCount + secondCount - equalsCount);
  124.  
  125.     return resultValue;
  126. }
  127.  
  128. /// <summary>
  129. /// Возвращает эквивалентные слова из двух наборов.
  130. /// </summary>
  131. /// <param name="tokensFirst">Слова из первого предложения.</param>
  132. /// <param name="tokensSecond">Слова из второго набора предложений.</param>
  133. /// <returns>Набор эквивалентных слов.</returns>
  134. private string[] GetFuzzyEqualsTokens(string[] tokensFirst, string[] tokensSecond)
  135. {
  136.     var equalsTokens = new List<string>();
  137.     var usedToken = new bool[tokensSecond.Length];
  138.     for (var i = 0; i < tokensFirst.Length; ++i)
  139.     {
  140.         for (var j = 0; j < tokensSecond.Length; ++j)
  141.         {
  142.             if (!usedToken[j])
  143.             {
  144.                 if (IsTokensFuzzyEqual(tokensFirst[i], tokensSecond[j]))
  145.                 {
  146.                     equalsTokens.Add(tokensFirst[i]);
  147.                     usedToken[j] = true;
  148.                     break;
  149.                 }
  150.             }
  151.         }
  152.     }
  153.  
  154.     return equalsTokens.ToArray();
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement