Введение…………………………………………………………..................................................3
1 Теоретические основы ……………………………………………………………………..….5
1.1 Исторические сведения…………………………………………………….……………......5
1.2 Обзор основных понятий……………………………………………….……………….......9
2 Алгоритмы поиска подстроки в строке………………………………………………………13
2.1 Виды алгоритмов поиска……………………………………………………………….……13
2.2 Реализация алгоритмов поиска……………………………………………………………...17
Заключение…………………………………………………………………….............................20
Список использованных источников………………………………………………………..….21
Приложение A. Алгоритм поиска подстроки в строке Робина-Карпа …………………….....22
Приложение B. Алгоритм поиска подстроки в строке Бойера-Мура ………………………..24
2
Введение
В современном мире информация представляет большую значимость в формировании
сообщества, а также страны. Непосредственно, системы поиска дают возможность пользователям
по одному слову либо сочетанию слов осуществлять отбор с невероятной правильностью. На
данный момент существуют также несколько систем, которые могут представить ряд вариантов
склонений введённого слова либо сочетания слов. Глобальные либо локальные сети в отсутствии
поисковых систем привели бы к тому, что пользователь обязан был бы помнить огромное число
интернет адресов, зачастую обладающие сокращёнными наименованиями. С введением разных
компьютерных технологий в процесс производства, становятся важными такие проблемы как:
сохранение крупных размеров сведений в носителях, скорость передачи, но кроме того
стремительный поиск необходимой информации. В генной инженерии поиск совпадений
строковых последовательностей применяется при анализе ДНК. В программировании - равно как в
одной из наиболее трудных областей компьютерной промышленности - благодаря поиску в
настоящее, время, возможно, отыскать погрешности, при лексическом рассмотрении
компьютерных проектов. Информация из разных баз данных, также делается недоступной для
извлечения в отсутствии надлежащего поиска согласно установленным характеристикам. Каждая
искательская концепция основывается в базе одного либо некоторых скомбинированных
алгоритмов. Любой метод выделяется собственной быстротой вычисления итога. Методы
вычисления строковых совпадений используются в таких сферах, как распознавание речи,
компьютерное зрение, криптография, сжатие данных, вычислительная геометрия также
молекулярная биология. Нереально вообразить всемирно знаменитую лингвистическую
концепцию ABBYY LINGVO в отсутствии стремительного поиска согласно словам, либо
концепцию WINDOWS в отсутствии способности поиска файлов. Важным условием оптимальной
поисковой концепции считается подсознательно-доступный интерфейс, что сможет помочь
пользователю отыскать требуемые предметы.
Целью этой курсовой работы является изучение основных алгоритмов поиска подстроки в
строковых последовательностях. В ходе достижения этой цели будут решены следующие задачи.
Первая заключается в изучении исторических сведений об алгоритмах. Без истории
невозможно представить себе развитие программирования, потому что на основе уже
разработанных алгоритмов, строятся новые или модернизируются уже существующие.
Программисты наших дней могут сделать множество качественных программ, только благодаря
огромному вкладу в это дело предыдущих поколений.
Вторая задача включает в себя выявление основных понятий, связанных с
программированием и алгоритмом поиска слов.
3
В третью задачу входит изучение архитектуры алгоритмов поиска текста в строке,
сравнение таких алгоритмов как:
4
1 Теоретические основы
В данной главе будут рассмотрены основные теоретические понятия
связанные с алгоритмами, алгоритмами поиска и алгоритмами поиска
подстроки в строке, и изучены исторические сведения связанные с ними.
5
Со временем, слово algorism (или algorismus) обрело значение способа выполнения
арифметических действий посредством арабских цифр, то есть на бумаге, без использования
абака. Абак - счётная доска, применявшаяся для арифметических вычислений приблизительно с V
века до н. э. в Древней Греции, Древнем Риме. Многие века абак был фактически единственным
средством для практичных вычислений, им пользовались и купцы, и менялы, и учёные.
Достоинства вычислений на счётной доске разъяснял в своих сочинениях такой
выдающийся мыслитель, как Герберт Аврилакский, ставший в 999 г. папой римским под именем
Сильвестра II. Новое с огромным трудом пробивало себе дорогу, и в историю математики вошло
упорное противостояние лагерей алгорисмиков и абацистов (иногда называемых гербекистами),
которые пропагандировали использование для вычислений абака вместо арабских цифр. Прошло
не одно столетие, прежде чем новый способ счёта окончательно утвердился, столько времени
потребовалось, чтобы выработать общепризнанные обозначения, усовершенствовать и
приспособить к записи на бумаге методы вычислений. В Европе учителей арифметики вплоть до
XVII века продолжали называть «магистрами абака», а сочинения по искусству счёта назывались
Алгоритмами.
Постепенно значение слова расширялось. Учёные начинали применять его не только к
сугубо вычислительным, но и к другим математическим процедурам. Например, около 1360 г.
французский философ Николай Орем написал математический трактат Algorismus proportionum
(«Вычисление пропорций»), в котором впервые использовал степени с дробными показателями и
фактически вплотную подошёл к идее логарифмов. Когда же на смену абаку пришёл так
называемый счёт на линиях, многочисленные руководства по нему стали называть Algorithmus
linealis, то есть правила счёта на линиях.
Первоначальная форма algorismi спустя некоторое время потеряла последнюю букву, и
слово приобрело более удобное для европейского произношения вид algorism. Позднее и оно,
подверглось искажению, скорее всего, связанному со словом arithmetic.
В XVIII веке в одном из германских математических словарей, Vollstandiges mathematisches
Lexicon, термин algorithmus всё ещё объясняется как понятие о четырёх арифметических
операциях. Но такое значение не было единственным, ведь терминология математической науки в
те времена ещё только формировалась. В частности, выражение algorithmus infinitesimalis
применялось к способам выполнения действий с бесконечно малыми величинами.
Пользовался словом алгоритм и Леонард Эйлер, одна из работ которого так и называется -
«Использование нового алгоритма для решения проблемы Пелля».
a. [
6
b. https://ru.wikipedia.org/wiki/Алгоритм#История_термина ]
Потребовалось ещё почти два столетия, чтобы все старинные значения слова вышли из
употребления. Этот процесс можно проследить на примере проникновения слова «алгоритм» в
русский язык.
Историки датируют 1691 годом один из списков древнерусского учебника арифметики,
известного как «Счётная мудрость». Это сочинение известно во многих вариантах и восходит к
ещё более древним рукописям XVI века. По ним можно проследить, как знание арабских цифр и
правил действий с ними постепенно распространялось на Руси.
Полное название этого учебника - «Сия книга, глаголемая по-эллински и по-гречески
арифметика, а по-немецки алгоритма, а по-русски цифирная счётная мудрость».
Таким образом, слово «алгоритм» понималось первыми русскими математиками так же, как
и в Западной Европе. Однако его не было ни в знаменитом словаре В.И. Даля, ни спустя сто лет в
«Толковом словаре русского языка» под редакцией Д.Н. Ушакова. Но слово «алгоритм» можно
найти в популярном дореволюционном Энциклопедическом словаре братьев Гранат, и в первом
издании Большой советской энциклопедии. Здесь оно трактуется как правило, по которому
выполняется то или иное из четырёх арифметических действий в десятичной системе счисления.
Однако к началу XX в. для математиков слово «алгоритм» уже означало любой арифметический
или алгебраический процесс, выполняемый по строго определённым правилам, и это объяснение
также даётся в следующих изданиях БСЭ.
Алгоритмы становились предметом всё более пристального внимания учёных, и
постепенно это понятие заняло одно из центральных мест в современной математике. Что же
касается людей, от математики далёких, то к началу сороковых годов это слово они могли
услышать разве что во время учёбы в школе, в сочетании «алгоритм Евклида». Несмотря на это,
алгоритм всё ещё воспринимался как термин сугубо специальный, что подтверждается
отсутствием соответствующих статей в менее объёмных изданиях. В частности, его нет даже в
десятитомной Малой советской энциклопедии (1957 г.), не говоря уже об однотомных
энциклопедических словарях. Но зато спустя десять лет, в третьем издании Большой советской
энциклопедии (1969 г.) алгоритм уже характеризуется как одна из основных категорий
математики, «не обладающих формальным определением в терминах более простых понятий, и
абстрагируемых непосредственно из опыта». Как мы видим, отличие даже от трактовки первым
изданием БСЭ разительное! За сорок лет алгоритм превратился в одно из ключевых понятий
математики, и признанием этого стало включение слова уже не в энциклопедии, а в словари.
Например, оно присутствует в академическом «Словаре русского языка» (1981 г.) именно как
термин из области математики.
7
Одновременно с развитием понятия алгоритма постепенно происходила и его экспансия из
чистой математики в другие сферы. И начало ей положило появление компьютеров, благодаря
которому слово «алгоритм» вошло в 1985 г. во все школьные учебники информатики и обрело
новую жизнь. Вообще можно сказать, что его сегодняшняя известность напрямую связана со
степенью распространения компьютеров. Например, в третьем томе «Детской энциклопедии»
(1959 г.) о вычислительных машинах говорится немало, но они ещё не стали чем-то привычным и
воспринимаются скорее, как некий атрибут светлого, но достаточно далёкого будущего.
Соответственно и алгоритмы ни разу не упоминаются на её страницах. Но уже в начале 70-х гг.
прошлого столетия, когда компьютеры перестали быть экзотической диковинкой, слово
«алгоритм» стремительно входит в обиход. Это чутко фиксируют энциклопедические издания. В
«Энциклопедии кибернетики» (1974 г.) в статье «Алгоритм» он уже связывается с реализацией на
вычислительных машинах, а в «Советской военной энциклопедии» (1976 г.) даже появляется
отдельная статья «Алгоритм решения задачи на ЭВМ». За последние полтора-два десятилетия
компьютер стал неотъемлемым атрибутом нашей жизни, компьютерная лексика становится всё
более привычной. Слово «алгоритм» в наши дни известно, вероятно, каждому. Оно уверенно
шагнуло даже в разговорную речь, и сегодня мы нередко встречаем в газетах и слышим в
выступлениях политиков выражения вроде «алгоритм поведения», «алгоритм успеха» или даже
«алгоритм предательства».
В данной работе также будет использовано понятие «алгоритма поиска строки в
подстроке». В развитии этого алгоритма принимали участие многие учёные.
Ричард Карп в 1987 году, вместе с Майклом Рабином, разработал алгоритм поиска
подстроки, названный в их честь.
Ричард Карп родился в 1935 году в семье учителя математики и директора средней школы
Эйбрахама Луиса Карпа и его жены Розы Карп в Бостоне, штат Массачусетс. С ним росли двое
младших братьев Роберт и Дэвид, и младшая сестра Кэролин. Окончив школу, Ричард поступил в
Гарвардский университет, где получил титулы бакалавра (1955), магистра наук (1956) и наконец
доктора философии по прикладной математике в 1959 году. После учёбы работал 9 лет в
исследовательском центре IBM. В 1968 году он получил профессуру по информатике, математике
и исследованию операций при калифорнийском университете Беркли, где и работает по сей день,
не учитывая четырёхлетнего перерыва на работу в университете Вашингтона. В 1971 году Карп
вместе с Джэком Эдмондсом разработал алгоритм для нахождения максимального потока в
транспортной сети. Год спустя, Карп опубликовал свой труд «Reducibility Among Combinatorial
Problems», в котором он доказал NP-полноту для 21 задачи.
Михаэль Рабин родился в 1931 году сыном раввина Исраэля Аврахама Рабина в городе
Бреслау (ныне Вроцлав), принадлежащему тогда к Пруссии. В 1935 году его семья эмигрировала в
8
Палестину. В 1953 году он получил титул магистра наук, закончив учёбу в Еврейском
университете в Иерусалиме. Три года спустя, в 1956 году, защитил диссертацию в Принстонском
университете и стал доктором философии. В настоящее время (сентябрь 2008 года) Майкл Рабин
занимается исследованиями в области компьютерной безопасности и преподаёт в Иерусалиме и
Гарварде.
В 1977 году были опубликованы результаты работ Д. Кнута, В. Пратта, Д. Морриса также
занимавшихся алгоритмами поиска.
Дональд Эрвин Кнут - американский учёный, почётный профессор в отставке
Стэнфордского университета и нескольких других университетов в разных странах, иностранный
член Российской академии наук, преподаватель и идеолог программирования, автор 19
монографий и более 160 статей, разработчик нескольких известных программных технологий.
Автор всемирно известной серии книг, посвящённой основным алгоритмам и методам
вычислительной математики, а также создатель настольных издательских систем TEX и
METAFONT, предназначенных для набора и вёрстки книг, посвящённых технической тематике.
Родился 10 января 1938 в США в семье преподавателя. Отец Дональда преподавал бухгалтерский
учёт, а также занимался печатным делом на дому как любитель. С юных лет в Дональде
наблюдалась склонность к математике, физике и музыке. Профессор Кнут удостоен премии
Тьюринга (1974), Национальная научная медаль США (1979) и AMS Steele Prize, премия Харви
(1995 год), премия Киото (1996) за достижения в области передовых технологий, премия имени
Грейс Мюррей Хоппер (1971).
Наиболее быстрый алгоритм среди алгоритмов общего назначения, предназначенных для
поиска подстроки в строке, был разработан Робертом Бойером и Джеем Муром в 1977 году.
Преимущество этого алгоритма в том, что ценой некоторого количества предварительных
вычислений над шаблоном, шаблон сравнивается с исходным текстом не во всех позициях - часть
проверок пропускаются как заведомо не дающие результата.
9
самостоятельными из-за окончания работы инструкций, от которых они находятся в зависимости,
имеют все шансы осуществляться в случайном режиме, параллельно либо одновременно, в случае
если это позволяют применяемые процессор и операционная система. Зачастую в качестве
исполнителя выступает некоторый механизм (компьютер, токарный станок, швейная машина),
однако представление метода необязательно относится к компьютерным программам, таким
образом, например, отчетливо описанный способ изготовления блюда, кроме того, считается
методом, в этом случае исполнителем считается индивид. Представление метода принадлежит к
первоначальным, основным, базовым понятиям математики. Вычислительные движения
алгоритмического характера (арифметические действия над целыми числами, нахождение
максимального общего делителя 2-ух чисел и т. д.) знакомы людям с глубочайшей древности. Но,
в очевидном варианте представление метода сложилось только в начале XX столетия. В
современном обществе метод в формализованном выражении составляет основу образования в
случаях, согласно подобию.
Существуют основные свойства алгоритма, которыми должен обладать любой из них:
- Детерминированность (определенность). Это свойство заключается в том, что при задании
одних и тех же исходных данных несколько раз алгоритм будет выполняться абсолютно
одинаково и всегда будет получен один и тот же результат. Свойство детерминированности
проявляется также и в том, что на каждом шаге выполнения алгоритма всегда точно известно, что
делать дальше, а каждое действие однозначно понятно исполнителю и не может быть истолковано
неопределенно. Благодаря этому свойству выполнение алгоритма носит механический характер.
- Массовость - выражается в том, что с помощью алгоритма можно решать не одну
конкретную задачу, а любую задачу из некоторого класса однотипных задач при всех допустимых
значениях исходных данных.
- Результативность - означает, что выполнение алгоритма обязательно должно привести к
решению поставленной задачи, либо к сообщению о том, что при заданных исходных величинах
задачу решить невозможно. Алгоритмический процесс не может обрываться безрезультатно.
- Дискретность - означает, что алгоритм состоит из последовательности отдельных шагов -
элементарных действий, выполнение которых не представляет сложности. Именно благодаря
этому свойству алгоритм может быть реализован на ЭВМ.
- Конечность - заключается в том, что последовательность элементарных действий
алгоритма не может быть бесконечной, неограниченной, хотя может быть очень большой (если
требуется, например, большая точность вычислений).
- Корректность - означает, что если алгоритм создан для решения определенной задачи, то
для всех исходных данных он должен всегда давать правильный результат и ни для каких
исходных данных не будет получен неправильный результат.
10
[ 2. Билл Смит. Методы и алгоритмы вычислений на строках. М.: Вильямс, 2006]
11
процесс вычисления, что, в свою очередь, приводит к увеличению значений констант
пропорциональности в их асимптотических оценках.
[ https://ru.wikipedia.org/wiki/Алгоритм#Свойства_алгоритмов ]
12
[https://neerc.ifmo.ru/wiki/index.php?title=Поиск_подстроки_в_строке ]
13
3. совпадение → сравнить вторые символы и так далее,
4. несовпадение → I:=I+1 и переход на пункт 2,
[ https://habr.com/ru/post/111449/ ]
14
Особенности КМП-поиска:
15
Из равенства ki= kj (mod q) не следует, что ki= kj (например, 31415=67399(mod 13), но это
не значит, что 31415=67399). Если ki= kj (mod q), то ещё надо проверить, совпадают ли строки
W[1…m] и T[s+1…s+m] на самом деле.
Если простое число q достаточно велико, то дополнительные затраты на анализ холостых
срабатываний будут невелики. В худшем случае время работы алгоритма РК — Θ((N-M+1)*M), в
среднем же он работает достаточно быстро – за время О(N+M).
Пример: Сколько холостых срабатываний k сделает алгоритм РК, если
q= 11, 13, 17. Пусть W={2 6}
16
Количество
Порядок
Название Среднее Худшее Препроцессинг Доп. память поисков. Описание
сравнен.
шаблонов
Данный алгоритм
использует
Алгоритм хэширование, что
Рабина- O(p+t)O( O(pt)O(p Single / снижает скорость в
O(p)O(p) O(1)O(1) Прямой
Карпа p+t) t) Finite среднем. Можно
модифицировать для
поиска нескольких
паттернов
Алгоритм
Кнута- O(p+t)O( O(p+t)O( Использует префикс-
O(p)O(p) O(p)O(p) Single Прямой
Морриса- p+t) p+t) функцию
Пратта
Считается наиболее
быстрым из
Алгоритм алгоритмов общего
Бойера- O(pt)O(p O(p+σ)O(p+ назначения.
O(t)O(t) O(p+σ)O(p+σ) Single Обратный
Мура t) σ) Использует эвристики.
Существует большое
количество
оптимизаций
17
if (P[j] != T[i+j])
{ found = 0;
break; }
if (found)
return i+1; }
else
{
t = (d*(t - ((tonum(T[i])*h) % q)) + tonum(T[i+m])) % q;
}
}
return -1;
}
18
BMT[(short)(substring[i])] = ssl - i - 1;
Pos = ssl - 1 ;
while (Pos < sl)
if (substring[ssl - 1 ] != string[Pos])
Pos = Pos + BMT[(short)(string[Pos])];
else
for (i = ssl - 2; i >= 0; i--){
if (substring[i] != string[Pos - ssl + i +1 ]) { //
Pos += BMT[(short)(string[Pos - ssl + i + 1])]-1;//
break; }
else
if (i == 0)
return Pos - ssl + 1; }
}
printf("\n");
return res; }
19
Заключение
В ходе выполнения данной курсовой работы были выполнены все поставленные задачи:
изучены исторические сведения об алгоритмах; выявлены основные понятия, связанные с
программированием и алгоритмом поиска слов; изучены архитектуры алгоритмов поиска
подстроки в строке и было проведено сравнение таких алгоритмов как: алгоритм прямого поиска;
алгоритм Д. Кнута, Д. Мориса и В. Пратта (КМП-поиск); алгоритм Р. Боуера и Д. Мура (БМ-
поиск); алгоритм Рабина-Карпа (РК-поиск). Так же выявлены положительные и отрицательные
моменты в процессе вычисления и реализованы алгоритмы поиска подстроки в строке на примере
двух алгоритмов: Рабина-Карпа и Бойера-Мура.
20
Список использованных источников
2. Кнут Д. Алгоритм Кнута-Морриса-Пратта
3. Билл Смит. Методы и алгоритмы вычислений на строках. М.: Вильямс, 2006..
4. Стивенс Р. Delphi. Готовые алгоритмы. Учебное пособие.
[Электронный ресурс]. – Режим доступа:
5. https://ru.wikipedia.org/wiki/Алгоритм#Свойства_алгоритмов
a. https://ru.wikipedia.org/wiki/Алгоритм#История_термина
6. https://habr.com/ru/post/111449/
7. https://neerc.ifmo.ru/wiki/index.php?title=Поиск_подстроки_в_строке
21
Приложение A.
#include <string.h>
#include <math.h>
#include <iostream>
#define tonum(c) (c >= 'A' && c <= 'Z' ? c - 'A' : c - 'a' + 26)
{ if (p == 0)
return 1;
if (p & 1)
else
return sqr; }
{ int i,j,p,t,n,m,h,found;
n = strlen(T);
m = strlen(P);
h = mod(d,m-1,q);
p = t = 0;
{ p = (d*p + tonum(P[i])) % q;
t = (d*t + tonum(T[i])) % q; }
{ if (p == t)
{ found = 1;
if (P[j] != T[i+j])
{ found = 0;
break; }
22
if (found)
return i+1; }
else
return -1; }
{ int sovp;
char T[200];
char P[100];
cin >> T;
cin >> P;
if(sovp)
else
cout<<"Not found";
system("pause");
return 0; }
23
Приложение B.
#include <stdlib.h>
#include <locale.h>
int sl = 0;
int ssl = 0;
sl++; }
ssl++; }
if (sl == 0)
printf("wrong string\n");
else if (ssl == 0)
printf("wrong substring\n");
else {
int i, Pos;
int BMT[256];
BMT[i] = ssl;
if (BMT[(short)(substring[i])] == ssl)
BMT[(short)(substring[i])] = ssl - i - 1;
Pos = ssl - 1 ;
if (substring[ssl - 1 ] != string[Pos])
else
24
break; }
else
if (i == 0)
printf("\n");
return res; }
char str[30];
char substr[30];
scanf("%s", str);
scanf("%s", substr);
return 0; }
25