Версия для печати темы (https://pro1c.org.ua/index.php?s=1ec83b6598f11699ff7c203d40567b48&showtopic=37739)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование обычных форм 1С 8.2 и не интерфейсной логики _ Необходим алгоритм сравнения строк: вычисление коэффициента "похожести" двух строк в диапазоне от 0 до 1 - 1С

Автор: cao0603 08.06.17, 18:38

Сабж.

Или необходима http://pro1c.org.ua/redirect.php?http://infostart.ru/public/146559/ обработка.


 ! 

http://pro1c.org.ua/index.php?act=announce&id=2: 5
 

Автор: daveal 09.06.17, 7:50

http://pro1c.org.ua/redirect.php?https://ru.wikipedia.org/wiki/Сходство_Джаро_—_Винклера
Думаю это подойдёт. Есть реализация на разных языках.

Автор: daveal 09.06.17, 9:15

Function getCommonCharacters(string1, string2, allowedDistance)

  str1_len = StrLen(string1);
  str2_len = StrLen(string2);
  temp_string2 = string2;

  commonCharacters = "";

  For i = 1 To str1_len Do
    // compare if char does match inside given allowedDistance
    // and if it does add it to commonCharacters
    lowwerBound = Max(1, i - allowedDistance - 1);
    upperBound = Min(i + allowedDistance, str2_len);
    noMatch = True;
    j = lowwerBound;
    While j <= upperBound And noMatch Do
        If Mid(temp_string2,j,1) = Mid(string1,i,1) Then
          noMatch = False;
          commonCharacters = commonCharacters + Mid(string1,i,1);
        EndIf;
        j = j + 1;        
    EndDo;    
  EndDo;

  return commonCharacters;
EndFunction

Function Jaro( string1, string2 )

  str1_len = StrLen(string1);
  str2_len = StrLen(string2);

  // theoretical distance
  distance = Int(Max( str1_len, str2_len ) / 2.0) - 1;

  // get common characters
  commons1 = getCommonCharacters( string1, string2, distance );
  commons2 = getCommonCharacters( string2, string1, distance );

  commons1_len = StrLen(commons1);
  commons2_len = StrLen(commons2);
  
  If commons1_len = 0 Or commons2_len = 0 Then
      Return 0;
  EndIf;  
  
  // calculate transpositions
  transpositions = 0;
  upperBound = min(commons1_len, commons2_len);
  
  For i = 1 To upperBound Do
      If Mid(commons1,i,1) <> Mid(commons2,i,1) Then
          transpositions = transpositions + 1;
      EndIf;
  EndDo;
  
  transpositions = transpositions/2;

  // return the Jaro distance
  return (commons1_len/str1_len + commons2_len/str2_len + (commons1_len - transpositions)/(commons1_len)) / 3.0;

EndFunction

Function getPrefixLength( string1, string2, MINPREFIXLENGTH = 4)

  n = min(MINPREFIXLENGTH, StrLen(string1), StrLen(string2));

  For i = 1 To n Do
      If ( Mid(string1,i,1) <> Mid(string2,i,1) ) Then
          // return index of first occurrence of different characters
          Return i-1;
      EndIf;
  EndDo;
  
  Return n;
EndFunction

Function JaroWinkler(string1, string2, PREFIXSCALE = 0.1)

  JaroDistance = Jaro(string1, string2);

  prefixLength = getPrefixLength(string1, string2);

  return JaroDistance + prefixLength * PREFIXSCALE * (1.0 - JaroDistance);
    
EndFunction


Но этот алгоритм не работает с перестановками слов.
Сравнение алгоритмов по функционалу http://pro1c.org.ua/redirect.php?https://asecuritysite.com/forensics/simstring

Автор: cao0603 09.06.17, 16:46

XBrut @ Вчера, 20:23 * ,
у меня есть например
болт 2-8-10-кд ост 133078
болт 3-8-12-ц ост 133078
и вывести насколько они совпадают

Автор: daveal 12.06.17, 8:02

Ну так этот алгоритм вернет 0,89777 для этих строк, а, например болт 2-8-10-кд ост 133078 и болт 3-8-10-кд ост 133078 будет 0,98400.
Проблема только будет с перестановками, например, если будет в одной строке "ост 133078", а в другой "133078 ост". Тогда нужно другие алгоритмы искать.
По ссылке на сравнение выше можно посмотреть какие результаты вернет тот или иной алгоритм.
А как нормализовать строки перед применением (привести к верхнему регистру или нижнему, убрать разделители или не убирать) - это уже зависит от входных данных.


Автор: cao0603 12.06.17, 18:48

daveal @ Сегодня, 9:02 * ,
да все верно, а вот надо как то нормализовать обе строки, а как?это вопрос, или чтобы алгоритм распознавал чисто по цифрам , а не просто символам

daveal @ Сегодня, 9:02 * ,
это я привел такой пример где две строки один в один идут, а есть строки где Вы видишь что они похожи, но из за разного форматирования они разные по алгоритму

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua