Кружок 1С #2. Двоичный поиск (бинарный, дихотомия) в 1С.
Разберем кейс поиска в упорядоченном массиве по алгоритму двоичного поиска в упорядоченном массиве, в нашем случае файле.
Статья на нашем сайте:
Условие задачи
Нужна возможность осуществлять анализ введенного пароля на то, что он скомпрометирован путем анализа файлов часто используемых паролей.
Ртого: Сѓ нас есть введенный пользователем пароль, Рё нам необходимо путем перебора нескольких макетов СЃ часто используемыми паролями, РІ которых РЅР° каждой строке введен пароль РІ нижнем регистре определить совпадает ли введенный пароль СЃ тем, который ввел пользователь СЃ теми паролями, которые есть РІ файле. Если РѕРЅ найден, надо написать, что пароль скомпрометирован. Обращаю внимание, что РјС‹ опускаем то, что регистр может быть РґСЂСѓРіРёРј. Будем введенную строку пользователя переводить РІ нижний регистр Рё проверять только маленькие Р±СѓРєРІС‹. Рто упрощает задачу.
Первый вариант решения “РІ лоб“
Р’ самом начале, СЏ попытался использовать РїРѕРёСЃРє “РІ лоб“. Рў.Рµ. берем РїРѕ очереди макеты СЃ паролями Рё строчка, Р·Р° строчкой сравниваем СЃ тем, что ввел пользователь. Нашли - отлично, пароль скомпрометирован, если РЅРµ нашли, то так Рё напишем.
Проблема оказалось в том, что для ~88000 часто используемых паролей это работает ОЧЕНЬ медленно. На моем компьютере это отрабатывало около 18 секунд. Пользователь не захочет ждать такое время. Значит нам нужен другой алгоритм.
Второй вариант решения: двоичный (бинарный) поиск или дихотомия
Дальше, я начал думать, как же можно было бы улучшить алгоритм. Рвспомнил про двоичный поиск. Начнем с определения из вики.
Двоичный (бинарный) РїРѕРёСЃРє (также известен как метод деления пополам или дихотомия) — классический алгоритм РїРѕРёСЃРєР° элемента РІ отсортированном массиве (векторе), использующий дробление массива РЅР° половины. Рспользуется РІ информатике, вычислительной математике Рё математическом программировании.
Важно, что все слова наших паролей упорядочены по алфавиту. Схематично алгоритм выглядит так:
Схема двоичного поиска
Предположим наше слово начинается на букву F.
1. В самом начале левой точкой мы берем букву A, правой букву Z. Центральная точка у нас M.
2. M нужная нам точка? Если бы это была искомая буква, то мы ее нашли и должны закончить, но нет, это не наша точка, продолжаем алгоритм.
3. В каком отрезке может находится нужная нам точка F в AM или MZ?
4. Наша искомая точка находится в AM, тогда в качестве левой точки выбираем А, в качестве правой, выбираем M и продолжаем, переходя на шаг 1.
Вариантов окончания работы алгоритма всего два: либо мы наткнемся на эту точку на очередном шаге и нужный элемент найден, либо у нас не останется больше точек и это будет означать, что мы ничего не нашли и элемент не найден.