Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Поиск в строке. Алгоритм Кнута, Мориса и Пратта

Приблизительно в 1970 г. Д. Кнут, Д. Морис и В. Пратт изобрели алгоритм, фактически требующий только N сравнений даже в самом плохом случае. Новый алгоритм основывается на том сообра­жении, что, начиная каждый раз сравнение образа с самого начала, мы можем уничтожать ценную ин­формацию. После частичного совпадения начальной части образа с соответствующими символами строки мы фактически знаем пройденную часть строки и можем «вычислить» некоторые сведения (на основе самого образа), с помощью которых потом быстро продвинемся по тексту. Приведенный пример поиска слова «иваны» показывает принцип работы такого алгоритма. Символы, подвергшиеся сравнению, здесь подчеркнуты. Обратите внимание: при первом несов­падении двух символов образ сдвигается на все прой­денное расстояние, поскольку меньшие сдвиги не мо­гут привести к полному совпадению

 

 

КМП-алгоритм записывается так (опять используется предикат Р (1.47) и Q (1.48))

i:=1; j:=1; (1.50)

WHILE (j <= M) AND (i <= N) DO BEGIN

(* Q(i-j) & P(i-j, j) *)

WHILE (j >= 1) AND (s[ i ] <> p[ j ]) DO j:=D;

i:=i+1; j:=j+1;

END;

Однако такая запись умышленно не совсем точная, поскольку в ней есть сдвиг на неопределенную вели­чину D. Вскоре мы к ней вернемся, а теперь сначала отметим, что условия Q(i-j) и P(i-j, j) сохра­няются как глобальные инварианты и к ним можно добавить отношения 1 ≤ i ≤ N и 1 ≤ j ≤ M. Это предполагает, что мы должны отказаться от соглашения, что i всегда отмечает в тексте текущее поло­жение первого символа образа. Точнее, выравненное положение образа теперь i - j.

Если алгоритм заканчивает работу по причине j=М+1, то из составляющей P(i-j, j) следует спра­ведливость P(i-М, М), т. е., согласно (1.47), сов­падение начинается с позиции i - М. Если же работа окончена из-за i = N+1, то поскольку j < М+1, из инва­рианта Q(i) следует, что совпадения вообще нет.

Теперь мы должны показать, что алгоритм ни­когда не делает инвариант ложным. Легко видеть, что в начале i=j=1, и он истинен. Сначала иссле­дуем эффект от двух операторов, увеличивающих i и j на единицу. Они, очевидно, не сдвигают образ вправо и не делают ложным Q(i – j), поскольку раз­ность остается неизменной. Но, может быть, они де­лают ложным P(i—j, j) - вторую составляющую ин­варианта? Обращаем внимание, что в этой точке истинно отрицание выражения в заголовке внутрен­него цикла, т. е. либо j < 1, либо si=pj. Последнее увеличивает частичное совпадение и устанавливает P(i-j, j+1), а первое так же постулирует истин­ность P(i-j, j+1). Следовательно, увеличение на единицу i и j не может также сделать ложным тот или другой инвариант. Но в алгоритме остается толь­ко еще присваивание j:=D. Мы просто постулируем, что значение D всегда таково, что замена j на D оставляет инвариант справедливым.

Для того чтобы найти соответствующее выраже­ние для D, мы должны вначале понять смысл этого присваивания. При условии что D < j, присваивание соответствует сдвигу образа вправо на j - D позиций. Естественно, мы хотим, чтобы сдвиг был настолько больше, насколько это возможно, т. е. D должно быть как можно меньше. Этот процесс показан на рис. 1.1.

i

  a b c d    
  a b c e    
  a b c d        
        a b c e  

 

j=4 D=1 j=1

 

Рис. 1.1. Присваивание j:=D сдвигает образ на j—D по­зиции вправо
(в данном случае D=1, до присваивания j=4).

 

Если инвариант P(i-j, j) & Q(i-j) после при­сваивания j значения D истинен, то перед ним долж­но быть истинно P(i-D, D) & Q(i-D). Это предусло­вие и будет поэтому нашим ориентиром при поиске под­ходящего выражения для D. Основное соображение:

благодаря P(i—j, j) мы знаем, что

si- j. … si-1 = p1 … pj-1

(мы только что просмотрели первые j символов образа и убедились в их совпадении с текстом). Поэтому условие P(i-D, D) с D ≤ j, т. е.

si-D. … si-1 = p1 … pD-1

превращается в

pj-D. … pj-1 = p1 … pD-1 (1.51)

и предикат ~P(i—k, М) для k=1...j-D (чтобы убедиться в инвариантности Q(i-D)) превращается в

pj-k. … pj-1 ≠ p1 … pk-1 (1.52)

Важный вывод: очевидно, что значение D опреде­ляется одним лишь образом и не зависит от строки текста. Условия (1.51) и (1.52) говорят, что для определения D мы должны для каждого j найти наименьшее D, т. е. самую длинную последователь­ность символов образа, непосредственно предшест­вующих позиции j, которая совпадает полностью с началом образа. Для каждого j такое D мы будем обозначать через dj. Так как эти значения зависят только от образа, то перед началом фактического поиска можно вычислить вспомогательную таблицу d;эти вычисления сводятся к некоторой предтрансляции образа. Соответствующие усилия будут оправ­данными, если размер текста значительно превышает размер образа (М<<N). Если нужно искать многие вхождения одного и того же образа, то можно пользоваться одними и теми же D. Приведенные примеры объясняют функцию D.

Примеры:

  a a a a a a       j=6; d[6]=4+1; (макс.сдвиг=j-d[j]=1) p[1]…p[4]=p[2]…p[5]
  a a a a a b      
    a a a a a b    
  a b c a b c       j=6; d[6]=2+1; (макс.сдвиг=j-d[j]=3) p[1]…p[2]=p[4]…p[5] p[1]…p[3]≠p[3]…p[5] p[1]…p[4]≠p[2]…p[5]
  a b c a b d      
        a b c a b c
  a b c d e a           j=6; d[6]=0+1; (макс.сдвиг=j-d[j]=5) p[1]…p[1]≠p[5]…p[5] p[1]…p[2]≠p[4]…p[5] p[1]…p[3]≠p[3]…p[5] p[1]…p[4]≠p[2]…p[5]
  a b c d e f          
            a b c d e f

Рис.1.2. Вычисление dj

 

Последний пример на рис.1.2. и примеры на рис.1.3. (два его частных случая) наводят на мысль, что мы можем поступать еще лучше: так как рj рав­но А вместо F (рис.1.3.), то соответствующий символ строки не может быть символом А из-за того, что условие si≠рj заканчивает цикл. Следовательно, сдвиг на 5 не приведет к последующему совпадению, и поэтому мы можем увеличить размер сдвига до шести (см. рис. 1.3., верхний пример). Учитывая это, мы пере­определим вычисление dj как поиск самой длинной совпадающей последовательности

p1. … pdj-1 = pj-dj … pj-1

с дополнительным ограничением pdj ≠ pj. Если ника­ких совпадений нет, то мы считаем dj=0, что указывает на сдвиг «на целый» образ относительно его текущей позиции (см. рис. 1.3., нижняя часть).

 

  a b c d e f          
  a b c d e a          
              a b c d e

j=6, d[6]=0; сдвиг=j-d[j]=6

 

 

  a b c d e f            
  a b c d e g            
              a b c d e f

j=6, d[6]=0; сдвиг=j-d[j]=6

 

Рис. 1.3. Сдвиг образа за последний символ

 

Ясно, что вычисление dj само представляет собой первое приложение поиска в строке, и мы для этого можем использовать быструю версию КМП-алгоритма. Это и демонстрирует программа 1.2, состоящая из двух частей. В первой читается строка s, а затем идут итерации, начинающиеся с чтения образа, затем следуют его предтрансляция и, наконец, сам поиск.

 

CONST Mmax = 100; Nmax = 1000; ESC = ЗЗС;

<== предыдущая лекция | следующая лекция ==>
Прямой поиск строки | Поиск в строке. Алгоритм Боуера и Мура
Поделиться с друзьями:


Дата добавления: 2014-01-13; Просмотров: 501; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.025 сек.