Upgrade to Pro — share decks privately, control downloads, hide ads and more …

№ 4. Алгоритмы поиска подстроки в строке, модули

B1196c22fd3ca181eec43e1b67823d3f?s=47 ОПК
March 01, 2021

№ 4. Алгоритмы поиска подстроки в строке, модули

1. Поиск подстроки в строке — метод грубой силы и идеи его ускорения.
2. Алгоритм Боуэра-Мура.
3. Алгоритм Рабина-Карпа.
4. Программирование как борьба со сложностью.
5. Программа как один большой черный ящик.
6. Декомпозиция на модули.
7. Пример модульной структуры: скачивалка изображений.
8. На что указывает граф связей между модулями?
9. Модуль = Интерфейс + Реализация.
10. Устройство модулей в Python.
11. Стандартная библиотека Python как набор модулей.
12. Почему интерфейс важнее реализации?
13. Операционная система как интерфейс.
14. Признаки хорошего интерфейса.

B1196c22fd3ca181eec43e1b67823d3f?s=128

ОПК

March 01, 2021
Tweet

Transcript

  1. ОСНОВЫ ПРОГРАММНОГО КОНСТРУИРОВАНИЯ Лекция № 4 
 1 марта 2021

    г.
  2. ПОИСК ПОДСТРОКИ В СТРОКЕ • Задача: дана строка — «стог

    сена» длины N (haystack). 
 Определить, встречается ли в ней строка-«иголка» длины M (needle) и если да, то на какой позиции . • Метод грубой силы: подставляем «иголку» к каждой возможной позиции в «стоге сена», покуда не совпадет или «стог» не кончится. 
 Количество сравнений: O((N−M)·M).
  3. АЛГОРИТМ БОУЭРА-МУРА (МОДИФИЦИРОВАННЫЙ) • Явно нет смысла сдвигать «иголку» на

    одну позицию вправо . • Хорошо бы как-то учесть частичное совпадение строк и не проверять все символы заново каждый раз. «стог сена» b c a b c b c b a a … «иголка» a a a a a
  4. СУТЬ АЛГОРИТМА • Подставляем «иголку» к началу «стога» (i =

    M−1). • Сравниваем символы с конца «иголки»: h[k] и n[j], уменьшая k и j (изначально k = i, j=M−1) . • Если j дошло до начала «иголки», подстрока найдена ! • Если на каком-то шаге h[k] ≠ n[j], то сдвигаем «иголку» на d[h[i]] вправо (i += d[h[i]]).
  5. МАССИВ СДВИГОВ d — хитрый массив, индексируемый символами x из

    конечного алфавита. Для каждого символа: • если x отсутствует в n, то d[x] равно M ; • если x – не последний в n, то d[x] равно расстоянию от последнего вхождения x в n до конца n ; • если x – последний в n, то d[x] равно расстоянию от предпоследнего вхождения x в n до конца n. n = "abcbc " d['b'] = 1 d['c'] = 2 d['a'] = 4 d[...] = 5
  6. АНАЛИЗ АЛГОРИТМА БОУЭРА-МУРА • На практике работает очень хорошо, вплоть

    до: 
 O(N/M). • В худшем случае (поиск "abbbb" в "bbbbbbbbbb"): 
 O((N–M)⋅M).
  7. АЛГОРИТМ РАБИНА-КАРПА Вместо сравнения подстрок будем использовать сравнение их хешей

    . • Хеш-функция быстро преобразует произвольную строку в некоторое численное значение, причем равные строки преобразуются в равные значения . • Например: 
 hash("abc") = (97⋅2562 + 98⋅2561 + 99⋅2560) % 997 Некое большое простое число Q Основание исчисления R
  8. СУТЬ АЛГОРИТМА • Tn — хеш «иголки» . • Th,k

    — хеш M символов «стога», начиная с позиции k . • Перебираем k = 0…(N–M) и сравниваем Tn и Th,k . • Если совпали, то проверяем посимвольно, и в случае совпадения – успех . • Иначе идем дальше.
  9. ХИТРОСТЬ ВЫЧИСЛЕНИЯ ХЕШЕЙ В «СТОГЕ СЕНА» • Th,k • Th,k+1

    • Если мы знаем Th,k, то за константное время можно вычислить Th,k+1: 
 Th,k+1 = (Th,k − RM−1·h[k])·R + h[k+M]. = RM−1·h[k] + RM−2·h[k+1] + … + R0·h[k+M–1 ] = RM−1·h[k+1] + RM−2·h[k+2] + … + R0·h[k+M ]
  10. АНАЛИЗ АЛГОРИТМА РАБИНА-КАРПА • В среднем алгоритм работает за O(N–M)

    . • При достаточно большом простом Q, вероятность ложных совпадений (1/Q) . • В худшем случае O((N–M)⋅M) . • Отлично подходит для поиска нескольких «иголок» в одном «стоге».
  11. АЛГОРИТМ КНУТА- МОРРИСА-ПРАТТА • В худшем случае работает за O(M+N)

    . • Предварительно строит по «иголке» двумерный массив сдвигов . • Во время прохода по «стогу», никогда не идет назад . • Оптимальный алгоритм, но непростой.
  12. ПРОФЕССИЯ: ПРОГРАММИСТ • Пожарные борются с огнем . • Педагоги

    борются с детьми . • Полиция борется с преступностью . • Программисты борются …
  13. … со сложностью!

  14. ЧТО СЛОЖНЕЕ?

  15. РАБОТА С ЧЕРНЫМИ ЯЩИКАМИ import blackbox blackbox.prepare() blackbox.work_hard()

  16. ЕСЛИ НЕТ ЧЕРНОГО ЯЩИКА? Сделать его с помощью других ящиков!

  17. Скачивалка изображений Динамическая память: malloc и free Динамический массив Низкоуровневые

    функции работы с сеть ю (connect, recv, send, close) Очередь Скачивание файла по адресу Распознавание и чтение форматов (jpg, png, ...) Алгоритм resize для изображений
  18. ДЕКОМПОЗИЦИЯ Нечто сложное Нечто более простое Нечто более простое Нечто

    более простое
  19. ПЕРВОЕ ПРЕДСТАВЛЕНИЕ МОДУЛЯ Имя Задача

  20. ПРОСТЕЙШИЕ СПОСОБЫ ДЕКОМПОЗИЦИИ • Взаимодействие с пользователем (User Interface) –

    отдельный модуль . • Обработка разных структур данных – в разных модулях (list, stack, queue, …) . • Элементы функциональности, близкие по смыслу – в один модуль (io, parse, errors) . • Если процесс естественным образом разбивается на отдельные шаги, то каждый шаг – в свой модуль (prepare, get_data, process, output).
  21. УТОЧНЕНИЕ ПРЕДСТАВЛЕНИЯ • Модули состоят из функций . • Функции

    вызывают другие функции, из своего модуля и из других модулей . • Вызовы функций – связи между модулями.
  22. КАРТИНКИ СВЯЗЕЙ Что проще? Мера сложности системы – количество связей.

    X Y Z X Y Z
  23. МЕРЫ ПРОТИВ СЛОЖНОСТИ Интерфейс Реализация Прозрачный ящик Черный ящик

  24. ИНТЕРФЕЙС И РЕАЛИЗАЦИЯ • Адресная книга : • Интерфейс: операции

    (добавить запись, найти по имени) . • Реализация операций: код функций, основанный на конкретном представлении хранилища и выбранных алгоритмах, а также вспомогательные функции.
  25. УСТРОЙСТВО МОДУЛЕЙ 
 В PYTHON • Каждый python-файл можно использовать

    как модуль . • Вспомогательные сущности именуются с подстрочника . • Использование модуля: •import mymodule
 mymodule.myfunc( ) •from mymodule import myfunc, myconst
 myfunc()
  26. EQUSOLVER.PY from math import sqrt def solve2(a, b, c): if

    a != 0: return _solve2_real(a, b, c) else: return solve1(b, c) def _solve2_real(a, b, c): d = b*b - 4*a*c if d > 0: x_1 = (-b - sqrt(d)) / (2 * a) x_2 = (-b + sqrt(d)) / (2 * a) return [x_1, x_2] else: ... def solve1(a, b): ...
  27. MAIN.PY import equsolver roots = equsolver.solve2(1, -5, 6) print(roots) #

    [2.0, 3.0]
  28. СТАНДАРТНАЯ БИБЛИОТЕКА PYTHON • math – математические функции . •

    time – функции работы со временем и датой . • random – функции для генерации случайных чисел . • sys – функции для взаимодействия со средой исполнения . • os – функции для работы с операционной системой.
  29. ПОЧЕМУ ИНТЕРФЕЙС ВАЖНЕЕ РЕАЛИЗАЦИИ? • На один интерфейс может быть

    несколько реализаций (но не наоборот!) . • Если интерфейс удачный, модуль легче повторно использовать . • Если интерфейс выпущен в широкую публику, его гораздо сложнее изменить . • Интерфейс — это то, что увидят другие, реализацию могут и не увидеть.
  30. ОПЕРАЦИОННАЯ СИСТЕМА КАК ИНТЕРФЕЙС ‣ What would you do if

    you had to do it over again ? ‣ Ken Thompson (the creator of UNIX): I’d spell creat with e. 

  31. ХОРОШИЙ ИНТЕРФЕЙС • Легко изучить . • Легко использовать, даже

    без документации . • Сложно использовать неправильно . • Код, написанный с помощью этого интерфейса, легко читать и поддерживать . • Достаточная сила (количество возможностей) . • Легкая расширяемость . • Подходит пользователям, которые будут его использовать.
  32. КОНЕЦ ЧЕТВЕРТОЙ ЛЕКЦИИ Очень трудно найти в тёмной комнате чёрную

    кошку, особенно, если её там нет!