Степень сходства двух наименований справочника

15.10.19

Разработка - Математика и алгоритмы

Статья посвящена исследованию следующего вопроса: необходимо сравнить 2 наименования справочников с целью вычисления их степени сходства. По задумке, степень сходства должна выражаться в процентах.

Скачать файлы

Наименование Файл Версия Размер
Степень сходства двух наименований справочника для 1С7.7
.ert 35,00Kb
1
.ert 35,00Kb 1 Скачать
Степень сходства двух наименований справочника для 1С8.х
.epf 10,87Kb
19
.epf 10,87Kb 19 Скачать

Задача возникла при попытках поиска элементов справочника номенклатуры для обновления значений реквизитов. Суть проблемы заключалась в неуникальности реквизитов для поиска (артикул, например) в пределах всего справочника, что приводило к ложной подстановке обновляемых реквизитов. 

В итоге, в качестве решения проблемы разработана модель сравнения наименования найденного элемента справочника с наименованием элемента, необходимого для обновления реквизитов. Таким образом, мы отсеиваем полностью несовпадающие по наименованию элементы справочника при неуникальных остальных реквизитах, по которым мы пытаемся спозиционироваться на элемент.

Существуют масса алгоритмов определения степени сходства 2-х текстов, после изучения которых, был выработан следующий алгоритм:

  1. Вычисляем длины наименований
  2. Принимаем за эталон наибольшую длину (для организации цикла)
  3. Принимаем наименование с наибольшей длиной за эталонную строку
  4. Попарно вычисляем число вхождений в обоих наименованиях каждого символа из эталонной строки
  5. Удаляем из наименований символы, для которых произведён поиск
  6. Складываем общее количество вхождений для каждого наименования
  7. После цикла вычисляем степень сходства по формуле (результат в процентах):
(Вхождение1/Вхождение2)*100
 

Здесь, "Вхождение1" - общее число вхождений каждого символа эталонной строки в первое наименование, "Вхождение2" - общее число вхождений каждого символа эталонной строки во второе наименование. 

Перед вычислением по формуле, в условном операторе, необходимо определить какое из наименований имеет наибольшее число вхождений.

Ниже представлен полученный код для платформы 1С Предприятие 7.7. Принимаются предложения по оптимизации.

//возвращает процент сходства 2-х наименований
Функция СходствоНаименований(Знач Наим1="",Знач Наим2="") 
    Наим1 = СокрЛП(Наим1);
    Наим2 = СокрЛП(Наим2);
    Наим1 = СтрЗаменить(Наим1,"  ",""); //Удаляем двойные пробелы
    Наим1 = СтрЗаменить(Наим1," ","");  //Удаляет одинарные пробелы
    Наим2 = СтрЗаменить(Наим2,"  ","");
    Наим2 = СтрЗаменить(Наим2," ","");
    //проверяем значения на схожесть  
    Длина1  = СтрДлина(Наим1);
    Длина2  = СтрДлина(Наим2);
    Если Длина1 > Длина2 Тогда
        Длина = Длина1;
	Стр   = Наим1;
    Иначе
	Длина = Длина2;
	Стр   = Наим2;
    КонецЕсли;
    Сч = 0; Вхождение1 = 0; Вхождение2 = 0;
    Пока (Стр<>"") Цикл
        Символ = Лев(Стр,1);
        Вхождение1 = Вхождение1+СтрЧислоВхождений(Наим1,Символ);
        Вхождение2 = Вхождение2+СтрЧислоВхождений(Наим2,Символ);
        Наим1 = СтрЗаменить(Наим1,Символ,"");
        Наим2 = СтрЗаменить(Наим2,Символ,"");
        Стр = Прав(Стр,СтрДлина(Стр)-1);
    КонецЦикла;
    Возврат  ?(Вхождение1>Вхождение2,Окр((Вхождение2/Вхождение1)*100,3,1),Окр((Вхождение1/Вхождение2)*100,3,1));
КонецФункции //СходствоНаименований()

Выявленные преимущества алгоритма:

  • Время исполнения кода на очень хорошем уровне (меньше 0.0001 сек.)
  • Переносимось алгоритма (не нужно подключать внешние компоненты)
  • Выходной показатель (процент степени сходства) соответствует различию входных данных

Выявленные недостатки:

  • Чувствительность алгоритма к сильному различию в количестве символов 2-х наименований (показатель степени сходства быстро снижается) 
  • При простой перестановке символов в разных наименованиях результат будет 100% сходства, что неверно.

Результаты экспериментов

Эксперимент 1:

  • Наименование1 = "A0900001N Угольник 1"х1"
  • Наименование2 = "CJ 65 V3 Лобзик"
  • Результат = 13.636%

Эксперимент 2:

  • Наименование1 = "Cъемник рулевых тяг и шаровых опор TOYA"
  • Наименование2 = "Cъемник рулевых тяг и шаровых опор  2-х позиционный, зев 20 мм"
  • Результат = 56.863%

Эксперимент 3:

  • Наименование1 = "MF 800 VE миксер Felisatti"
  • Наименование2 = "MF1200/VE2 миксер Felisatti"
  • Результат = 84.000%

Возможное решение описанных выше недостатков

Метод написан на базе платформы 1С:8 пользователем DrBlack

Функция ПолучитьПроцентСходстваНаименований_2(Знач НаимСравн="", МассивСлов, ОбщДлинаСлов)
    СуммаСовпадений = 0;
    Для Каждого ТекСлово Из МассивСлов Цикл     
        Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(ТекСлово) Тогда
            СчНачало = СтрДлина(ТекСлово);
        Иначе
            СчНачало = Макс(3, СтрДлина(ТекСлово)-4);
        КонецЕсли;
        МаксСовпадений = 0;
        Для Сч = СчНачало По СтрДлина(ТекСлово) Цикл          
            ТекОтрезокЛево = Лев(ТекСлово,  Сч);
            ТекОтрезокПрав = Прав(ТекСлово, Сч);          
            МаксСовпадений = Макс(МаксСовпадений, ?(СтрЧислоВхождений(НаимСравн, ТекОтрезокЛево)>0, Сч, 0), ?(СтрЧислоВхождений(НаимСравн, ТекОтрезокПрав)>0, Сч, 0));     
        КонецЦикла;   
        СуммаСовпадений = СуммаСовпадений + МаксСовпадений;       
    КонецЦикла;   
    ПроцентСовпадения = Окр(Мин(ОбщДлинаСлов, СуммаСовпадений) / ОбщДлинаСлов * 100, 3, 1);   
    Возврат ПроцентСовпадения;
КонецФункции

Входные параметры:
НаимСравн - строка, с которой надо сравнить
МассивСлов - эталонная строка, заранее разбитая на составляющие
ОбщДлинаСлов - общая длинна слов в МассивСлов для вычисления коэф. схожести

Суть данного метода - устранить недостатки метода из топика.

Описание колонок на скрине:
Процент1 - сравнение методом из топика
Процент2 - сравнение методом пользователя  DrBlack по вхождению слов (не короче 4х символов)
Процент3 - усредненный коэф (Процент1 + Процент2 х 2) / 3

СПАСИБО ЗА ВНИМАНИЕ!

[Обновление, 15.10.19] Добавлены обработки для 1С7.7 и 1С8.х, реализующие задачу при помощи алгоритмов из публикации.

Сходство Различие Алгоритм Реквизит Наименование Номенклатура

См. также

Экспорт нескольких MXL таблиц в один XLS файл, на отдельные листы. Простой алгоритм

Загрузка и выгрузка в Excel Математика и алгоритмы Платформа 1С v7.7 Платформа 1С v8.3 Бесплатно (free)

Статья посвящена распространённому вопросу - как сохранить несколько таблиц (отчетов) в формате MXL, с которым работает 1С, на отдельные листы одного Excel файла. Освещается простой алгоритм решения проблемы штатными средствами, без использования внешних модулей и библиотек (не относящихся к 1С и Excel).

23.11.2015    18902    etmarket    14    

20

.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия

Разработка внешних компонент Математика и алгоритмы Платформа 1С v7.7 Платформа 1С v8.3 Бесплатно (free)

Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия, а так же генерация модулей на C# и 1С для подключения к событиям. Использование DynamicMethod и ILGenerator. Представлены примеры для использовании событий System.IO.FileSystemWatcher (Ожидает уведомления файловой системы об изменениях и инициирует события при изменениях каталога или файла в каталоге.) и SerialPort (обработка сканера штрих кода подключенного к COM порту). Обертка позволяет использовать классы .Net только на языке 1С. Реализация 1C Messenger описанного здесь http://infostart.ru/public/434771/

12.11.2015    51085    Serginio    36    

57

Задача про сгибание листка

Математика и алгоритмы Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Часто при приеме на работу встречается задача про сгибание листка

1 стартмани

26.02.2013    19480    11    Sbelyi78    38    

9

Универсальная печать таблицы значений

Математика и алгоритмы Оперативный учет 7.7 Бухгалтерский учет 7.7 Расчет 7.7 Конфигурации 1cv7 Россия Абонемент ($m)

Универсальная печать таблицы значений, которую не стыдно прикрутить к рабочей базе данных. Группировка данных, подсчет итогов, составление диаграмм, выгрузка в быстрый доступ к исходной ТЗ.

1 стартмани

23.05.2012    14763    66    McSeem    3    

8

Тригонометрические функции в 7.7

Математика и алгоритмы Платформа 1С v7.7 Конфигурации 1cv7 Россия Абонемент ($m)

Алгоритм получения значения тригонометрических функций путем разложения их в ряд Тейлора

1 стартмани

04.03.2012    8589    4    nysysimara    10    

5

Таблица Значений для анализа при разработке и отладке

Математика и алгоритмы Платформа 1С v7.7 Конфигурации 1cv7 Россия Абонемент ($m)

Таблица Значений, для анализа данных при разработке и отладке.

1 стартмани

30.11.2011    16464    46    Boog    10    

15
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. vcv 89 25.02.15 10:17 Сейчас в теме
Без толковой внешней компоненты, реализующей нечеткое сравнение, толку от подобной обработки мало.
Как будете оценивать степень сходства у "Cъемник рулевых тяг" и "Cьёмник руливых тяг" ?
Посмотрите, например, на http://infostart.ru/public/70044/
2. etmarket 890 25.02.15 11:00 Сейчас в теме
(1) vcv, для такого сравнения, алгоритм даст результат около 100% (а точнее 97%). Что, собственно, и требуется для реализации.

Не стояла задача организации нечеткого сравнения. Поскольку обработка происходит для большого объема данных, результат должен выдаваться за минимальное количество времени. Полученный процент существенно вносит ясность в различие, что достаточно для принятия решения.

Поэтому ваша критика несущественна. Но все-равно спасибо за отзыв!
7. JohnyDeath 301 25.02.15 11:52 Сейчас в теме
Посмотрите на ВК отсюда: http://infostart.ru/public/15765/
Она может найти схожесть между такими наименованиями как "Водка Посольская" и "Vodka Posolskaja"
Присоединяюсь к (1) и (4). Такое надо в ВК выносить, на 1С слишком муторно все будет
V.Nikonov; +1 Ответить
8. etmarket 890 25.02.15 12:48 Сейчас в теме
(7) JohnyDeath, к сожалению, не будут удовлетворены требования производительности.
Спасибо за ссылку на публикацию.
Приведённый алгоритм тоже имеет право на существование и успешно доказал свою применимость.
9. gaglo 25.02.15 15:05 Сейчас в теме
(8) В том-то и дело, что границы применимости данного алгоритма не сформулированы. Пытался вчитаться в начальные абзацы статьи, но... не вышло у меня. И фразы вроде " процент существенно вносит ясность в различие" - мне не помогли.
Ясно только, что это не "нечеткое сравнение", как сказано в (2).
Хотелось бы формулировок в виде "из записей с одинаковым артикулом отсеивали те, которые содержат совсем непохожие наименования, а те, что остались, предлагали для ручного выбора".
Кстати, без ВК обходились в статье про Русский Metaphone (и др.).
10. etmarket 890 25.02.15 15:12 Сейчас в теме
(9) gaglo, поиск решения такой простейшей задачи всегда остаётся актуальным, поскольку идеальных решений не существует. Меня заинтересовала разработка самого быстрого алгоритма, который удовлетворит поставленным задачам. И данный алгоритм во всём удовлетворил моему техническому заданию. Поэтому я его и представил на суд сообществу.

К сожалению, ни один из критикантов не предложил способов улучшения метода без существенного усложнения, кроме как взять готовый ВК. Поэтому вижу свою затею в публикации статьи пустой!

П.С. Я старался доходчиво объяснить применимость метода, но, видимо, очень по-простому не умею.
13. vcv 89 25.02.15 15:43 Сейчас в теме
(10)
Меня заинтересовала разработка самого быстрого алгоритма, который удовлетворит поставленным задачам.

Сильно подозреваю, что использование ВК будет работать быстрее, чем посимвольное перебирание строк на языке 1С.
К сожалению, ни один из критикантов...

Ну прямо "критикантов"! Вы взялись за задачу, которая нормального решения без ВК не имеет. Без ВК получается или хреново, или тормозно. Тормозно, конечно, относительно возможных объёмов. Вот у меня порядка 20 тысяч номенклатурных позиций. Средняя длина наименований порядка 40-50 символов. Слабо представляю, что бы по такому объёму искать схожие наименования посимвольным перебором.
...не предложил способов улучшения метода без существенного усложнения, кроме как взять готовый ВК.

Если никак нельзя ВК...
Попробуйте заменять в наименовании буквы на фонетически сходные. Например, в наименовании "Водка Посольская" заменять В на Ф, О на А, З на С и так далее. Символы вроде Ь Ъ совсем убирать. Все знаки препинания заменять на пробелы. Заменять сходно написанные латинские буквы на русские. Строки, естественно, привести к единому регистру. Получившуюся строку поделить по словам.
Два списка слов из двух строк уже сравнивать.
15. etmarket 890 25.02.15 15:53 Сейчас в теме
(13) vcv,
Сильно подозреваю, что использование ВК будет работать быстрее, чем посимвольное перебирание строк на языке 1С.

Работа с ВК по производительности в РАЗЫ дольше, чем простым перебором символов. Откройте отладчик и проверьте 2 куска кода, выполняющих аналогичную задачу, но один из которых использует ВК.
Вы взялись за задачу, которая нормального решения без ВК не имеет.

Вы это утверждаете, потому что сами представления не имеете как это сделать.
Получившуюся строку поделить по словам. Два списка слов из двух строк уже сравнивать.

Наконец хоть какой то совет. Благодарю.
17. vasiliy_b 284 25.02.15 16:20 Сейчас в теме
(10) хотите способ улучшения алгоритма, их есть у меня.
Вам необходимо учитывать не только наличие символа со сравниваемой строкой но и позицию символа в строке, т.е чем ближе стоят друг к другу, тем больше добавляем вес данного совпадения, чем они дальше тем меньше. Так-же не помешает сравнивать не только посимвольно но и анализируя совпадение цепочки символов, чем больше цепочка символов с одинаковыми значениями тем коэфицент выше..
А вообще вы взялись за не простую задачу... если бы все было так просто, то я бы уже давно себе свой яндексогугл сделал =)

С уважением Ваш критикан =)

хм... не успел дочитать в (14) все уже описали подробней.
etmarket; +1 Ответить
18. etmarket 890 25.02.15 16:31 Сейчас в теме
(17) vasiliy_b, такая идея давно в голове была. Тут могут возникнуть проблемы, если не удалить все мешающие символы (пробелы, запятые, точки, скобки, проценты и т.д.), а также если в каком то наименовании при опечатке поставили 2 одинаковых символа вместо одного. И тогда, так называемый весовой коэффициент, только ухудшит положение дел.

Спасибо за дельный совет! :-)

П.С. Никто и не говорит, что задача простая. Она только кажется таковой. Но и попытки решить задачу не могут быть тщетными, если приложить к этому должные усилия. Собрать по крупицам идеи и синтезировать алгоритм.
3. ManyakRus 483 25.02.15 11:09 Сейчас в теме
4. kapustinag 25.02.15 11:17 Сейчас в теме
(0) Больше того, что-то сомнительно, что ищете действительно "Сходство", а не нечто другое. Поясню на примере:
Первое наименование: "АБВГДЕЖЗИЙКЛМН"
Второе наименование: "НМЛКЙИЗЖЕДГВБА"
(одно отличается от другого просто тем, что записано наоборот).
Для каждого символа будет найдено ровно одно вхождение.
Что, 100% сходство?
okiam; ZOMI; vasiliy_b; JohnyDeath; vcv; +5 Ответить
5. vcv 89 25.02.15 11:24 Сейчас в теме
(4) kapustinag, Точно, "кран" и "нарк" близнецы-братья со 100% совпадением %)
JohnyDeath; +1 Ответить
6. etmarket 890 25.02.15 11:45 Сейчас в теме
(4) kapustinag, вы правы, есть недостаток алгоритма в этом плане. Но поскольку простая перестановка символов в строке приводит к потере смысла наименования (строка становится случайным набором символов), то этот момент тоже несущественен. Никто не будет создавать наименование с непонятным набором символов, который случайно совпадёт с другим наименованием по частоте вхождений символов.
Ваши предложения по доработке?
11. loekyn 19 25.02.15 15:31 Сейчас в теме
То, что результатом сравнения будет ерунда уже писали выше.
Также непонятно зачем нужна 1-я строчка в
Наим1 = СтрЗаменить(Наим1," ","");
Наим1 = СтрЗаменить(Наим1," ","");

Одной второй недостаточно?

ИМХО правильно было бы сравнивать не вхождение символов а целых слов. Здесь тоже куча подводных камней в виде окончаний, опечаток и пр. Вот для сравнения отдельных слов предложенный алгоритм худо бедно подошел бы, только надо добавить контроль позиции символов в проверяемых словах при сравнении.

То, что "алгоритм быстрый" малоценно, т.к. на выходе чушь. Выдаваемые проценты - цифра ни о чем. Что там автор получил подсчитав количество одинаковых буковок в 2х строчках для меня загадка.
JohnyDeath; ojiojiowka; Идальго; +3 Ответить
12. etmarket 890 25.02.15 15:42 Сейчас в теме
(11) loekyn, первая строка удаляет двойной пробел, вторая одинарный. Замена одинарного пробела на пустой символ в некоторых случаях не отрабатывает замену двойного. Если не верите, можете самолично провести эксперимент.

На выходе не чушь, а объективные данные, которые помогли решить проблемы. Смотрите раздел "Результаты экспериментов".
14. Vortigaunt 96 25.02.15 15:48 Сейчас в теме
Когда-то стояла задача найти в справочниках "одинаковые" адреса торговых точек. Код приводить не буду. Распишу простым язком алгоритм, который использовал для сравнения строк.
1. Обрезать пробелы слева и справа и привести обе строки в верхний регистр.
2. Убрать мусор (точки, запятые, скобки)
3. Найти самую длинную совпадающую последовательность символов. Запомнить её длину и вырезать из сравниваемых строк.
4. Из оставшегося опять найти самую длинную последовательность символов и ёё длину приплюсовать к результату пункта 3.
Так до тех пор пока не останутся одиночные символы.
5. Вычислить отношение полученного результата к максимуму длин двух строк.
Получаем показатель от 0 до 100% насколько адреса совпадают.
P.S. В алгоритме нужно ограничить минимальную длину последовательности получаемую в пунктах 3 и 4 (опытным путем от 2х до 4х символов), а то получим сумму из единичек по всем символам.
user1150141; eeeio; JohnyDeath; ffgnebel; V.Nikonov; Mi4man; etmarket; +7 Ответить
16. etmarket 890 25.02.15 15:54 Сейчас в теме
(14) Vortigaunt, класс! Надо попробовать.
19. V.Nikonov 120 25.02.15 19:34 Сейчас в теме
В моей практике требовалось найти похожее (получить список похожих) из некоего справочника. Заполнялось некое соответствие 2х справочников...

1. Исходный образец разбивался на слова и грузился во временную таблицу.
2. Запросом считалось количество совпадений с весовым коэффициентом 1 (хотя можно использовать длину слова).
3. Максимальное число получалось при совпадении целой фразы Наименования.
4. На выходе найденные элементы сортировались по убыванию веса.

Если первый элемент из найденного списка имел значительно больший вес перед вторым, то подставлялось совпадение. Иначе список использовался для ручного выбора из списка. Именно этот алгоритм можно дополнить совпадением символов.

Но основная задача не просто сравнить, а найти безошибочно точное соответствие эталона в неком списке.
При посимвольном сравнении практически невозможно выбрать правильный вариант: Ищем "Пентиум II" среди "Пентиум II", "Пентиум III" и "Пентиум-4". Разность весового показателя будет слишком мала для принятия решения.

Использование ВК замедляет запуск поиска (требуется предварительная подготовка и передача списка в котором будет поиск), но сам поиск на несколько порядков быстрее (следствие откомпилированного процессорного кода ВК).
JohnyDeath; etmarket; +2 Ответить
20. _Konstantin_ 25.02.15 21:06 Сейчас в теме
Лет пять назад была такая же проблема в результате ВК по быстродействию лучше всего.
Забыл автора теории подобного поиска, но суть сравнения состоит в том что:кроме "Попарно вычисляем число вхождений в обоих наименованиях каждого символа из эталонной строки" надо еще сравнивать сочетание 2-х символов в каждой строке с последующим смещением на 1 символ, для улучшения та же операция но уже по 3 символа, правда тормозит страшно.
Этот алг. реализован в ВК от сюда http://infostart.ru/public/15765/
21. CheBurator 3119 26.02.15 00:31 Сейчас в теме
Посмотрите также сюда http://infostart.ru/public/14255/
Сделано на strmatch
Сама вк и ее исходники выложены на портале
Ищет весьма качественно особенно в длинных наименованиях в тч учитывает фонетические совпадения
Заявляю ответственно ибо на этой вк держится куча сравнилок и грузилок прайсов
На ее основе автоматизировано несколько контор
От фармации с мегапрайсами в пятнадцать тысяч наименований
От сетки ларьков по продаже дисков и чехлов
Магазин детских игрушек
Контора по торговле бытовой техникой
Это то что помню навскидку
Evil Beaver; etmarket; +2 Ответить
23. cool.vlad4 2 26.02.15 01:18 Сейчас в теме
(21) CheBurator, исходники ВК разве выложены? если не затруднит, то покажите где
22. CheBurator 3119 26.02.15 00:33 Сейчас в теме
Если к результатам работы данной вк подключить чуток эмпирики в соотвествии со специализацией наименований то результат считаю превосходен
Также был заказ по радиодеталям
А там осложнено это тем что наименования у них короткие и буквенноцифровые и все похоже на все
Добавление эмпирики позволило получить очень неплохие результаты
24. jobkostya1c_ERP 100 26.02.15 09:33 Сейчас в теме
Погляжу как основу как алгоритм нечеткого поиска.
25. etmarket 890 26.02.15 09:41 Сейчас в теме
(24) kostyaomsk, если не затруднит, когда будет готов ваш алгоритм, выложите его здесь в комментариях. У нас тут активное обсуждение и мозговой штурм :-)
26. cool.vlad4 2 26.02.15 15:56 Сейчас в теме
добавлю свои пять копеек.все зависит от постановки задачи. если задача найти схожие по звучанию, написанию это одно, про это писали выше. есть куча алгоритмов. по написанию есть метод n-грамм. есть куча других алгоритмов. и вообще можно взять sphinx и посмотреть его (я его кстати пробовал в 1С использовать, там есть квази-MySQL база, через которую можно запросы на неком подмножестве диалекта посылать, но отказался поскольку там есть требование иметь ключ как id - int или int64 ,что довольно затратно к каждой таблице делать еще таблицы из id в guid. хотя sphinx хорош скоростью обновления индексов). но если задача стоит сложного сравнения/поиска фраз , которые ничего общего по звучанию могут не иметь , например - "клейкая лента" и "скотч", то тут имхо нужно создавать поиск по онтологиям, создавать словарные базы, базы сокращений, базы семантик, парсить каждую фразу в дерево, а потом сравнивать деревья по весам ветвей. я не стал настолько углубляться в эту тему. не было смысла. видел только какие-то иностранные коммерческие системы в гугле, которые продаются за кучу денег, как они работают, не знаю)
27. CheBurator 3119 27.02.15 00:02 Сейчас в теме
Стрматч также хорош тем что там можно задавать веса цифр что повышает процент похожести
Это хорошо канает на всяких емкостях и литражах где надо чтобы равно было 200 мл и 0.2 л
28. DrBlack 23 14.07.16 10:32 Сейчас в теме
Мало ли кому пригодится, по этому выложу свой код:
Функция ПолучитьПроцентСходстваНаименований_2(Знач НаимСравн="", МассивСлов, ОбщДлинаСлов)

	СуммаСовпадений = 0;
	
	Для Каждого ТекСлово Из МассивСлов Цикл
		
		Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(ТекСлово) Тогда
			СчНачало = СтрДлина(ТекСлово);
		Иначе
			СчНачало = Макс(3, СтрДлина(ТекСлово)-4);
		КонецЕсли;
		МаксСовпадений = 0;
		
		Для Сч = СчНачало По СтрДлина(ТекСлово) Цикл
			
			ТекОтрезокЛево = Лев(ТекСлово,  Сч);
			ТекОтрезокПрав = Прав(ТекСлово, Сч);
			
			МаксСовпадений = Макс(МаксСовпадений, ?(СтрЧислоВхождений(НаимСравн, ТекОтрезокЛево)>0, Сч, 0), ?(СтрЧислоВхождений(НаимСравн, ТекОтрезокПрав)>0, Сч, 0));
			
		КонецЦикла;
		
		СуммаСовпадений = СуммаСовпадений + МаксСовпадений;
		
	КонецЦикла;
	
	ПроцентСовпадения = Окр(Мин(ОбщДлинаСлов, СуммаСовпадений) / ОбщДлинаСлов * 100, 3, 1);
	
	Возврат ПроцентСовпадения;
КонецФункции
Показать

Входные параметры:
НаимСравн - строка, с которой надо сравнить
МассивСлов - эталонная строка, заранее разбитая на составляющие
ОбщДлинаСлов - общая длинна слов в МассивСлов для вычисления коэф. схожести

Суть данного метода - устранить недостатки метода из топика.

Описание колонок на скрине:
Процент1 - сравнение методом из топика
Процент2 - сравнение моим методом по вхождению слов (не короче 4х символов)
Процент3 - усредненный коэф (Процент1 + Процент2 х 2) / 3
Прикрепленные файлы:
CheBurator; etmarket; +2 Ответить
29. etmarket 890 14.07.16 12:28 Сейчас в теме
(28) DrBlack, спасибо за ваш комментарий.
30. DrBlack 23 14.07.16 14:19 Сейчас в теме
(29) да незашто :)

Тестировал дальше, в общем похоже победа полная, результат интересный, файл прикрепил
И обновите статью, а то те кто будут искать, могут не дочитать до конца, а проблема-то решена... ;)

Прикрепленные файлы:
CheBurator; etmarket; +2 Ответить
31. Glebis 13 09.06.18 11:28 Сейчас в теме
Уж простите за поднятие старой темы, но другого алгоритма анализа схожести не нашел.

Не понял необходимость параметра ОбщДлинаСлов, какое число туда нужно помещать? Почему этот параметр нельзя вычислить перед перебором слов из массива? Или это средняя длина слов в массиве?
32. etmarket 890 10.06.18 15:51 Сейчас в теме
(31) Ну это суммарная длина строки по всем словам из массива. Можно это значение рассчитать внутри метода, чтобы избавить от параметра.
34. DrBlack 23 18.10.19 10:00 Сейчас в теме
(32) Любые операции со строками затратны по времени, по этому лучше рассчитать заранее и передавать параметром
35. Nikifforoff96 17.01.20 14:10 Сейчас в теме
(31) Попробуйте алгоритм сравнение строк триграммами.
Вместо поиска вхождений символов или целых слов можно искать вхождения триграмм.
"Поднятие старой темы" -> под одн дня нят яти тие иес ест ста тар аро рой ойт йте тем емы
И дальше считать процент триграмм, которые присутствуют в фразе, по которйо производится сравнение.
etmarket; +1 Ответить
36. etmarket 890 17.01.20 18:08 Сейчас в теме
(35) стоит попробовать. И сравнить с двумя другими способами.
37. CheBurator 3119 17.01.20 22:16 Сейчас в теме
(36) еще есть "расстояние Левенгука" и еще какоето (какое-то - то же есть на сатйе).
38. etmarket 890 18.01.20 00:25 Сейчас в теме
(37) векторный поиск можно попробовать прикрутить. По принципу распознавания образов в аудио и видеосигнале.
39. Nikifforoff96 20.01.20 09:27 Сейчас в теме
(38) Если брать вектор целой фразы, то перестановка слов очень сильно повлияет на его расположение в системе координат. А если вектор каждого слова, то по точности сравнения операция будет сопоставима с обычным процентом побуквенного вхождения.
В аудио и видеосигналах ключевое значение имеет порядок данных, а в случае с фразами ключевое значение имеет наличие определенных корней и буквенных конструкций, их порядок не так важен.
40. Nikifforoff96 20.01.20 09:27 Сейчас в теме
(37)
расстояние Левенгука
вы про Расстояние Левенштейна?
41. CheBurator 3119 20.01.20 14:58 Сейчас в теме
(40) Точно! ;-)
просто копаешься в багах, вот Левенгук и лезет в голову
42. webdimon 03.06.20 10:48 Сейчас в теме
(41) А есть реализация по этому методу?
43. CheBurator 3119 04.06.20 03:57 Сейчас в теме
(42) есть. на 7.7 я много и аквтивно это использовал. Поищи на порталде "Удар по бездуховности" в моем профиле - это простенький демо-пример
44. etmarket 890 30.11.22 10:22 Сейчас в теме
(35) одно из лучших решений при сравнении
33. etmarket 890 15.10.19 16:17 Сейчас в теме
[Обновление, 15.10.19] Добавлена обработка для 1С7.7, реализующая задачу при помощи алгоритмов из публикации.
45. CheBurator 3119 30.11.22 12:38 Сейчас в теме
(33) по коду для 77
Наим1 = СтрЗаменить(Наим1," ",""); //Удаляем двойные пробелы
- так не сработает, проверь на "Хрень с тремя и больше пробелами между словами"
46. fixin 4252 05.03.23 19:45 Сейчас в теме
Спасибо, применил у клиента. Работает более-менее нормально. Он грузит наименования от поставщика, поставщик постоянно их меняет.
Оставьте свое сообщение