Улучшенный алгоритм Левенштейна для 1С: интеллектуальное сравнение строк

07.11.25

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

Данная внешняя обработка для платформы 1С:Предприятие реализует усовершенствованный алгоритм Левенштейна для вычисления схожести строк с учетом различных лингвистических особенностей русского языка. В отличие от классической реализации, этот алгоритм учитывает фонетические, визуальные и контекстные особенности набора текста.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Улучшенный алгоритм Левенштейна для 1С: интеллектуальное сравнение строк
.epf 14,32Kb
8 2 150 руб. Купить
Только алгоритм Левенштейна (без дополнительных проверок)
.epf 6,81Kb
1 1 850 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Ключевые возможности:

📊 Умное вычисление расстояния между строками

  • Расширенный алгоритм Левенштейна с адаптивными весами замены символов

  • Процентное выражение схожести от 0% до 100%

  • Нормализация входных данных (автоматическое удаление пробелов и приведение к нижнему регистру)

🎯 Учет лингвистических особенностей:

 

1. Фонетическая идентичность

 

Учитывает буквы, которые звучат одинаково:

"е" <-> "э", "и" <-> "ы", "о" <-> "а", "г" <-> "х", "ч" <-> "щ" ...

 

2. Частые орфографические ошибки

 

Распознает типичные замены:

"з" <-> "с", "т" <-> "д", "п" <-> "б", "ж" <-> "ш", "в" <-> "ф" ...

 

3. Визуальное сходство

 

Учитывает похожие по начертанию буквы:

"ш" <-> "щ", "м" <-> "н", "и" <-> "й", "ц" <-> "у", "л" <-> "п" ...

 

4. Соседние клавиши на клавиатуре

 

Определяет вероятные опечатки из-за близкого расположения клавиш в русской раскладке.

 

5. Транслитерация

 

Распознает замены русских букв на похожие латинские:

"а" <-> "a", "е" <-> "e", "у" <-> "y", "о" <-> "o", "с" <-> "c" ...

 

6. Учет частотности букв

 

  • Редкие буквы ("ф", "ц", "щ", "э", "ъ") - высокая стоимость замены

  • Частые буквы ("а", "о", "е", "и", "н") - низкая стоимость замены

Гибкая настройка параметров

Обработка позволяет включать/выключать различные типы проверок через структуру параметров или в пользовательском интерфейсе:

 

Настройка весов алгоритма

В данной функции вы сможете самостоятельно установить коэффициенты для настройки точности работы алгоритма (чем больше коэффициент "скидка", тем выше будет результат сравнения, если условие проверки было выполнено).

Функция ПолучитьСтоимостьЗамены(Символ1, Символ2, СтруктураПараметров) // Основные настройки весов данного алгоритма
    Символ1 = Символ1;
    Символ2 = Символ2;
	КоэффициентЧастотности = 1;
	Стоимость = 1; // Значение, которое показывает как сильно отличаются символы
	Скидка = 0;    // Значение, которое уменьшает стоимость
	 
    // Полное совпадение
    Если Символ1 = Символ2 Тогда
        Возврат 0; // Если символы идентичны стоимость = 0;
    КонецЕсли;
	
    // Фонетически идентичные звуки (минимальная стоимость) 
	Если СтруктураПараметров.ПроверитьФонетическуюИдентичность Тогда
	    Если ПроверитьФонетическуюИдентичность(Символ1, Символ2) Тогда
	        Скидка = Скидка + 0.3; // 30% скидка
		КонецЕсли;
	КонецЕсли;   
	
	// Буквы, которые часто путают (средняя стоимость) 
	Если СтруктураПараметров.ПроверитьЧастыеОшибки Тогда
		Если ПроверитьЧастыеОшибки(Символ1, Символ2) Тогда
			Скидка = Скидка + 0.25; // 25% скидка
		КонецЕсли;
	КонецЕсли;
	
	// Похожие по начертанию буквы  
	Если СтруктураПараметров.ПроверитьВизуальноеСходство Тогда
		Если ПроверитьВизуальноеСходство(Символ1, Символ2) Тогда
			Скидка = Скидка + 0.15; // 15% скидка
		КонецЕсли;
	КонецЕсли;
	
	// Соседние клавиши на клавиатуре
	Если СтруктураПараметров.ПроверитьСоседниеКлавиши  Тогда
		Если ПроверитьСоседниеКлавиши(Символ1, Символ2) Тогда
			Скидка = Скидка + 0.15; // 15% скидка
		КонецЕсли;
	КонецЕсли;
	
	// Буква случайно написана на английском   
	Если СтруктураПараметров.ПроверитьТранслитерацию Тогда	
		Если ПроверитьТранслитерацию(Символ1, Символ2) Тогда
			Скидка = Скидка + 0.2; // 20% скидка
		КонецЕсли;
	КонецЕсли;             
	
	// Стоимость от частоты употребления букв в русском языке 
	Если СтруктураПараметров.УчестьЧастотностьБукв Тогда
		КоэффициентЧастотности = УчестьЧастотностьБукв(Символ1, Символ2);
	КонецЕсли;
	 
	Стоимость = Макс(0.1, Стоимость - Скидка) * КоэффициентЧастотности;
	
    // Полная замена
    Возврат Стоимость;
КонецФункции

 

 

Гибкая настройка параметров

Обработка позволяет включать/выключать различные типы проверок через структуру параметров или в пользовательском интерфейсе:

СтруктураПараметров = Новый Структура;

СтруктураПараметров.Вставить("ПроверитьСоседниеКлавиши",Истина);
СтруктураПараметров.Вставить("ПроверитьТранслитерацию",Истина);
СтруктураПараметров.Вставить("ПроверитьТранспозициюСимволов",Истина);
СтруктураПараметров.Вставить("ПроверитьФонетическуюИдентичность",Истина);
СтруктураПараметров.Вставить("ПроверитьЧастыеОшибки",Истина);
СтруктураПараметров.Вставить("ПроверитьВизуальноеСходство",Истина);
СтруктураПараметров.Вставить("УчестьЧастотностьБукв",Истина);

 

Технические особенности

 

Архитектура решения

  1. Модульная структура - разделение на основные и вспомогательные функции

  2. Гибкая система весов - адаптивная стоимость замены символов

  3. Оптимизация производительности - эффективное использование массивов

 

Алгоритмические улучшения

  • Транспозиция символов - учет перестановки соседних букв

  • Динамические коэффициенты - автоматическая корректировка весов

  • Нормализация результата - приведение к интуитивно понятному проценту схожести

 

Области применения

  • Поиск дубликатов в справочниках контрагентов, товаров, номенклатуры

  • Коррекция опечаток при вводе данных пользователями

  • Нечеткий поиск в больших массивах информации

  • Сравнение наименований при интеграциях и загрузках данных

 

Преимущества перед классическим алгоритмом

Критерий       Классический Левенштейн            Улучшенный алгоритм
Учет фонетики                          Нет                 Да
Учет раскладки клавиатуры                          Нет                 Да
Распознавание транслитерации                          Нет                 Да
Учет частотности букв                          Нет                 Да
Гибкая настройка                          Нет                 Да

 

Заключение

Данная обработка представляет собой инструмент для решения практических задач сравнения строк в системах на платформе 1С. Благодаря учету множества лингвистических и поведенческих факторов, алгоритм обеспечивает значительно более точные результаты по сравнению с классическими методами, что делает его незаменимым в задачах очистки данных и нечеткого поиска.

Обработка может встраиваться в справочник "Дополнительные отчеты и обработки" или открываться как внешняя. Также обработка совместима с платформами 1С:Предприятие 8.n

 

Бонус

Тут представлен полный код из второй обработки "Только алгоритм Левенштейна (без дополнительных проверок)". С помощью него будет легче понять саму работу алгоритма, которая заключается в создании матрицы и дальнейшем её заполнении с получением конечного результата.

&НаКлиенте
Функция ВыполнитьОбработку()
	Если ЗначениеЗаполнено(Строка1) И ЗначениеЗаполнено(Строка2) Тогда
		РасстояниеЛевенштейна = РасчитатьРасстояниеЛевенштейна(); 
			НаибольшаяДлинаСтроки = Макс(СтрДлина(Строка1),СтрДлина(Строка2));
		Сходство = (1 - РасстояниеЛевенштейна / НаибольшаяДлинаСтроки) * 100; // Преобразование полученного расстояния в проценты
	КонецЕсли;
КонецФункции

&НаКлиенте
Функция ПолучитьМассивИзСтроки(Строка) // Массив, где каждый элемент массива это символ переданной строки
	МассивСтрок = Новый Массив;
	Для Счетчик = 1 По СтрДлина(Строка) Цикл
		Символ = Прав(Лев(Строка,Счетчик),1); 
		МассивСтрок.Добавить(Символ);
	КонецЦикла; 
	Возврат МассивСтрок;
КонецФункции

&НаКлиенте
Функция ПолучитьМатрицу(Строка1, Строка2) // Матрица размером - длина первой строки на длину второй строки
	Матрица =  Новый Массив;
	ПерваяСтрока = Истина;
	Для Счетчик1 = 0 По СтрДлина(Строка2) Цикл
		СтрокаМатрицы = Новый Массив; 
		СтрокаМатрицы.Добавить(Счетчик1);
		Для Счетчик2 = 1 По СтрДлина(строка1) Цикл
			Если ПерваяСтрока Тогда
				СтрокаМатрицы.Добавить(Счетчик2);	
			Иначе	
				СтрокаМатрицы.Добавить(Неопределено);	
			КонецЕсли;
		КонецЦикла;
		ПерваяСтрока = Ложь;
		Матрица.Добавить(СтрокаМатрицы);
	КонецЦикла;
	Возврат Матрица;
КонецФункции

&НаКлиенте
Функция РасчитатьРасстояниеЛевенштейна() // Заполняем последовательно матрицу
	Матрица = ПолучитьМатрицу(Строка1, Строка2); 
	Массив1 = ПолучитьМассивИзСтроки(Строка2);
	Массив2 = ПолучитьМассивИзСтроки(Строка1);
	НомерСтрокиМатрицы = 0;
	Для каждого Элемент1 Из Массив1 Цикл 
		НомерСтрокиМатрицы = НомерСтрокиМатрицы + 1;
		НомерКолонкиМатрицы = 0;	
		Для каждого Элемент2 Из Массив2 Цикл   
			НомерКолонкиМатрицы = НомерКолонкиМатрицы + 1;
			ЭлементМатрицы1 = Матрица[НомерСтрокиМатрицы-1][НомерКолонкиМатрицы-1]; 
			ЭлементМатрицы2 = Матрица[НомерСтрокиМатрицы][НомерКолонкиМатрицы-1];
			ЭлементМатрицы3 = Матрица[НомерСтрокиМатрицы-1][НомерКолонкиМатрицы];
			НаименьшийЭлемент = Мин(ЭлементМатрицы1, ЭлементМатрицы2, ЭлементМатрицы3); // Выбираем наименьшее значение из трех соседних элементов матрицы
			Если Элемент1 <> Элемент2 Тогда // Если символы двух строк не равны тогда к выбранному ранее наименьшему элементу прибавляем стоимость(1)
				Матрица[НомерСтрокиМатрицы][НомерКолонкиМатрицы] = НаименьшийЭлемент + 1;
			Иначе
				Матрица[НомерСтрокиМатрицы][НомерКолонкиМатрицы] = НаименьшийЭлемент;	
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	Возврат Матрица[НомерСтрокиМатрицы][НомерКолонкиМатрицы]; // Это последний элемент полученной матрицы, который и является расстоянием Левенштейна
КонецФункции

 

Проверено на следующих конфигурациях и релизах:

  • 1С:ERP Управление предприятием 2, релизы 2.5.24.68

Вступайте в нашу телеграмм-группу Инфостарт

обработка 1С:Предприятие демонстрация открытый код памятка инструмент разработчика математика алгоритмы сравнение строк внешняя обработка ERP

См. также

Математика и алгоритмы Программист 1C v8.2 1C:Бухгалтерия Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    12190    stopa85    12    

42

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    19190    user1959478    57    

39

Математика и алгоритмы Разное 1С v8.3 1C:Бухгалтерия Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    11657    maksa2005    8    

27

Математика и алгоритмы Инструментарий разработчика Программист 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    19271    11    SpaceOfMyHead    20    

64

Математика и алгоритмы Программист 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    13112    RustIG    9    

30

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

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

23.11.2022    12241    gzharkoj    15    

27

Математика и алгоритмы Программист 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    11349    8    kalyaka    11    

45

Математика и алгоритмы Программист 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    14355    fishca    12    

39
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user-z99999 76 07.11.25 16:19 Сейчас в теме
Можно добавить (учитывать или наоборот не учитывать в коде):
ь ъ
тире и другие знаки
две буквы нн
цифры

Тогда похожесть повыситься.
2. InFlach 35 07.11.25 16:35 Сейчас в теме
(1) Проверка на пропуск "ь", "ъ" есть в одной из функций, что касается символов, с ними сложнее, придется отдельно "учить" алгоритм правилам пунктуации, а вот проверку на двойные согласные, в принципе, можно поместить, буду иметь ввиду)
3. tormozit 7319 08.11.25 09:31 Сейчас в теме
Подобные вычисления на языке 1С выполняются очень медленно с разрешенной отладкой и поэтому на больших объемах имеет смысл значительно ускорить их выполнение путем однострочной записи https://infostart.ru/1c/articles/1732527/
InFlach; VyacheslavShilov; +2 Ответить
7. booksfill 10.11.25 12:55 Сейчас в теме
(3)
Подобные вычисления на языке 1С выполняются очень медленно с разрешенной отладкой


Да и без разрешенной отладки очень медленно. Думаю, при реальных объемах это станет серьезной проблемой.

Наверное, лучше воспользоваться возможностью работать с js.
Да и выглядеть это будет проще, например, вот код разбиения на строки (одна строка):

Строка2.split("");


Сравните с :
&НаКлиенте
Функция ПолучитьМассивИзСтроки(Строка) // Массив, где каждый элемент массива это символ переданной строки
	МассивСтрок = Новый Массив;
	Для Счетчик = 1 По СтрДлина(Строка) Цикл
		Символ = Прав(Лев(Строка,Счетчик),1); 
		МассивСтрок.Добавить(Символ);
	КонецЦикла; 
	Возврат МассивСтрок;
КонецФункции
Показать


А вот заполнение строки матрицы:
function fillArray(nArg) {
let isFirstString = true; 
let n = nArg;   
 let f = function getAr() {
    res =  Array.from({length: n }, (_, i) =>
         (isFirstString? i + 1: undefined));
    isFirstString = false;
    return res;
  }
  return f;
}

const myF = fillArray(5);
Показать


Если что, я JavaScipt практически не знаю, но даже на моем уровне не вижу проблем.
8. InFlach 35 10.11.25 14:42 Сейчас в теме
(7)
Строка2.split("");

Совсем забыл про метод "СтрРазделить()", благодарю), что касается матрицы, она формируется довольно быстро, тут можно использовать разные подходы на ваше усмотрение(смотрел на выборке 1000 строк), а вот заполнятся она уже сильно медленнее в функции: "РасчитатьРасстояниеЛевенштейна". Тут и в массивах много значений по индексу ищется и расчеты есть, а если строка сама по себе длинная, то все сильно медленнее работает. Если есть идеи как лучше оптимизировать данную функцию, буду очень благодарен.
9. InFlach 35 10.11.25 14:49 Сейчас в теме
(3) Протестировал однострочный вариант, код как минимум в два раза быстрее начал выполняться, но, к сожалению, вся читаемость теряется. Так что, если редактировать код нет необходимости, то можно смело проводить рефакторинг
12. tormozit 7319 10.11.25 17:45 Сейчас в теме
(9) Если ты читал статью, то должен был заметить что читаемость сохраняется в пассивной красивой копии кода.
4. tormozit 7319 08.11.25 09:39 Сейчас в теме
Часто сравнивают не слова, а фразы (например, договор контрагента) или верблюжие цепочки слов (например, ДоговорКонтрагента). Можно сделать надстройку для этого алгоритма, чтобы он вычислял степени похожести между всеми парами СловоИзФразы1-СловоИзФразы2 и далее подбирал оптимальные пары слов и далее уже считал суммарное расстояние между фразами слов. В русском языке порядок слов не играет большой роли не небольших расстояниях. Поэтому порядком слов для коротких фраз можно пренебречь.
5. BigB 193 08.11.25 20:03 Сейчас в теме
А как быть с Е и Ё?
Например: Фёдор и Федор
6. InFlach 35 08.11.25 22:14 Сейчас в теме
(5) Такая проверка есть в алгоритме, соответственно если написано "е", вместо "ё", то функция возвращает довольно низкое расстояние Левенштейна, что показывает большую точность сравнения в результате
10. mkalimulin 1600 10.11.25 15:22 Сейчас в теме
Так, и какова эффективность в сравнении с векторами?
Какое у вас будет расстояние между "кроссовки" и "обувь для бега"?
11. InFlach 35 10.11.25 16:24 Сейчас в теме
(10) С векторами не сравнивал. Если не использовать дополнительные опции алгоритма, то расстояние будет равно 0, если использовать то результат сравнения будет ~8%, потому что некоторые буквы пройдут какие-то проверки
13. mkalimulin 1600 10.11.25 17:54 Сейчас в теме
(11) Что значит расстояние 0? Полное отличие?
14. InFlach 35 10.11.25 18:03 Сейчас в теме
(13) Прошу прощения за недоразумение, не расстояние 0, а процент сходства ноль, соответственно - полное отличие
15. mkalimulin 1600 10.11.25 18:08 Сейчас в теме
(14) Вектор в этом случае даст большое сходство. Потому что работает со смыслами, а не только с формами, как Левенштейн. Отсюда вопрос, зачем сейчас вообще пользоваться этим алгоритмом, если есть более универсальный инструмент?
16. InFlach 35 10.11.25 18:53 Сейчас в теме
(15) Например, если вам необходимо сопоставить тысячу позиций написанной вручную номенклатуры из экселя в 1С, не прибегая к каким-либо сторонним программам и не обучая нейросеть (если она есть в принципе и уже интегрирована). Что касается сравнения по смыслу, его очевидно не будет, это не поиск соответствий по ключевым словам, это сравнение символов и вычисление количества операций для дальнейшего определения схожести строк, тут только математика и дополнительные проверки, в основном, для русского языка. Данный код не будет возвращать никакого сходства при сравнении "огонь" и "пламя", его задача сравнить "корпус_металл_441_продажа" и "ропус_метал_441_прджа", а после сказать, что это строки очень похожи.
17. InFlach 35 10.11.25 19:09 Сейчас в теме
(15) Также, обратите внимание на сам код, алгоритм Левенштейна выступает основным телом, которое показывает довольно точное сравнение двух строк, а дальше к нему очень легко можно встроить любую проверку, как раз поиск по смыслу или проверку на ошибки, которую я как раз таким способом и присоединил. Но каждая дополнительная проверка - это время, так что на большую выборку скорее всего придется выбирать между длительностью и дополнительной точностью
Для отправки сообщения требуется регистрация/авторизация