Алгоритм Кнута, Морриса и Пратта (КМП)

 

     Этот алгоритм был создан в 1970 году и получил свое название от имен его разработчиков. Он состоит из двух этапов: подготовительного и основного.

     На подготовительном этапе учитывается структура подстроки. Для этого формируется массив D, в котором учитывается совпадения символов подстроки с началом подстроки следующим образом: нулевой элемент массива D получает значение равное -1. Далее для каждой позиции j, совпадающей с началом подстроки, вычисляется максимальное количество предшествующих ей символов. Если же совпадений нет, то соответствующий элемент массива D равен -1. Размерность массива D равна длине подстроки.

     Теперь рассмотрим основной этап. Поиск начинается со сравнения первого символа строки с первым символом подстроки. В случае несовпадения происходит сдвиг подстроки на количество символов, указанных соответствующим элементом массива D. Если совпадения подстроки со строкой не будет (то есть данной подстроки в строке нет), то программа выйдет из цикла для поиска подстроки, когда i будет равняться длине строки, то есть если ни один символ подстроки не совпадает ни с одним символом строки, то программа выполнит N сравнений, если же совпадения отдельных элементов подстроки(но не всей подстроки со строкой) будут найдены, то в наихудшем случае потребуется N+M сравнений. Если же совпадение подстроки со строкой обнаружится сразу, то потребуется M cравнений.

{kmp.pas

Сайт Algorithm (http://www.algorithm1.narod.ru/)

Автор проекта: Galina}

uses Crt;

const Mmax=100;

          Nmax=10000;

          Esc=#27;

var I, J, K, L, M, N : integer;

      Ch : char;

      P : array [0..Mmax-1] of char;

      S : array [0..Nmax-1] of char;

      D : array [0..Mmax-1] of integer;

begin

  write('Введите строку : ');

  N := 0; Ch := ReadKey;

  While (Ch <> #13) and (N < Nmax-1) do

   begin

    write(Ch);

    S[N] := Ch;

    N:=N+1;

    Ch := ReadKey

   end;

  writeln;

  write('Введите подстроку : ');

  M := 0;

  Ch := ReadKey;

  While (Ch <> #13) and (M < Mmax-1) do

   begin

    write(Ch);

    P[M] := Ch;

    m:=m+1;

    Ch := ReadKey;

   end;

  writeln;

  write('Поиск подстроки : ');

  if Ch=Esc then Exit;

  J := 0; K := -1; D[0] := -1;

  while J < M-1 do

   begin

    while (K >= 0) and (P[J] <> P[K]) do

      K := D[K];

    J:=J+1;

    K:=K+1;

    if P[J]=P[K] then D[J] := D[K]

                      else D[J] := K;

   end;

  J := 0;

  I := 0;

  K := 0;

  while (J < M) and (I < N) do

   begin

     while K<=I do

      begin

       Write(S[K]);

       K:=K+1;

      end;

     while (J >= 0) and (S[I] <> P[J]) do

      J := D[J];

     I:=I+1; J:=J+1;

  end;

  writeln;

  if J = M then writeln('Образец в строке присутствует')

              else writeln('Образец в строке отсутствует');

end.

Автор проекта: Galina
Hosted by uCoz
  % (' )/0./  6 <-1--  B D 5.-?@AI1F8BF<-/VPG M3J3S0J dA= dBAu?5/JNs0uu1i1 Dx8F4Rn<ѓ…^ †-l D34‰„n^A‹|A 9S | `”SzљJy\qxћA™oY]-q¶C LCXґQR  2FBXЉ[‰  Є~ ;=@ehО_2  ( Э %** Я Ю* ЭлмнопрстуфхцчшщъыьэюяЪ$ & Ю ЯбЪд и+ ( 1gќЄ6ЃV/– ’K Бx Йw "љ°z–gBu rjn D/ПЦ •yќnљ MГ5”{R#eЊДzџ Б0fy53µћ М ’1CN H m L2K§>B L mОћJ] Б