{"id":4098,"url":"\/distributions\/4098\/click?bit=1&hash=4a2746815553d402e055c9b00a2035b35e47c0edcda5fd7253d5e57f885e8ecc","title":"\u0410\u0444\u0435\u0440\u0438\u0441\u0442\u043a\u0430, \u0440\u0435\u0431\u0451\u043d\u043e\u043a \u0438 \u043f\u0430\u043d\u043a \u2014 \u0447\u0442\u043e \u043e\u0434\u0435\u0436\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u0445?","buttonText":"\u0423\u0437\u043d\u0430\u0442\u044c","imageUuid":"e6048338-fd6d-53fa-aaf4-387384748bf7"}

[Техпоп] Расстояние Левенштейна для работы с текстом — как найти, насколько похожи две строки

Что это, зачем это и как я это использовал в реальном проекте.

Что это?

Здесь можно просто пересказать википедию. Расстояние Левенштейна — это количество простых операций над символами, которое нужно сделать с одной строкой, чтобы получить другую. Под простыми операциями я имею в виду замену, вставку и удаление символов. Названо в честь Владимира Левенштейна, который в 1965 году начал заниматься подобными задачами.

Например, расстояние между словами «корона» и «корова» равно 1 — нужно заменить один символ, чтобы из одного получить второе. «лол» в «ололо» можно превратить за два шага, а «муха» в «слон» превращается за 4 шага — у них вообще ни одной буквы не совпадает.

Зачем это?

Ну, раз тут сравниваются строки, то скорее всего это как-то полезно при работе с текстом. Википедия говорит, что это используется, например, при поиске опечаток и даже при сравнении цепочек генов — их тоже можно представить в виде последовательностей символов.

Я бы хотел подробнее остановиться на поиске опечаток. На работе одна из моих, так сказать, областей ответственности — это система локализации и инструменты для нее. У нас постоянно добавляются новые предметы в игру, а у каждого предмета есть ключ локализации. Когда игрок видит предмет в игре, игра берет ключ для этого предмета, ищет для него перевод в системе локализации и показывает игроку.

Проблема в том, что команда локализации и команда художников работают относительно независимо. Локализаторы переводят названия предметов, а потом через инструменты локализации добавляют их в игру. Художники делают предметы и добавляют их в игру через другие инструменты. Иногда из-за этого появляются опечатки в ключах локализации — либо у художников, либо у локализаторов. Причем опечатки обычно всего в одном символе. SuperCoolItems вместо SuperCoolItem. Или BFG9000large вместо BFG9000Large. Из-за того, что реальный ключ не совпадает с тем, что есть в системе локализации, получается баг.

Получаются косяки вроде такого. Это просто пример, я не разрабатывал Tyranny. Steam Community

Чтобы решить эту проблему, я добавил инструмент для проверки локализации предметов. Он сканирует все предметы в игре и ищет для них локализацию. Если локализация не найдена, то он пробегается по всем существующим ключам локализации и ищет ближайшие, то есть с наименьшим расстоянием Левенштейна. Если расстояние равно 1, то вполне возможно, что это опечатка и нужно просто исправить ключ. После этого багов с локализацией стало меньше.

Алгоритм

А хз, если честно, какой там алгоритм. В моем коде на Java это выглядит так:

LevenshteinDistance levenshteinDistance = LevenshteinDistance.getDefaultInstance(); Integer distance = levenshteinDistance.apply(keyname, existingKeyname);

Да, я просто использую готовый алгоритм. Расстояние Левенштейна достаточно старая и популярная штука — алгоритм его расчета есть чуть ли не в стандартной библиотеке. Я хотел развить эту мысль в полноценное размышление, нужно ли программистам знать алгоритмы, но оно получилось больше, чем я ожидал, поэтому я вынес его в отдельный пост.

Котики просто так Instagram
0
1 комментарий
Denis Kuandykov

Оч крутая инфа!
Спасибо, пищи есчо

Ответить
Развернуть ветку
-6 комментариев
Раскрывать всегда
null