Ассоциативный способ сопоставления с двумерным образцом 1. ОСНОВНЫЕ ПОНЯТИЯ И ОБОЗНАЧЕНИЯ Обозначим через А конечный алфавит, через М множество имен, имеющее мощность не более счетной. Определение 1. Пара (символ алфавита, имя) называется клеткой и обозначается (a, m) A M . Символ a называется состоянием клетки, m – именем клетки. Определение 2. Множество клеток W A M , в котором нет двух клеток с одинаковыми именами, называется клеточным множеством. Определение 3. Конечное клеточное множество W = { (a 1 , m1 ) , (a 2 , m 2 ) , …, (a n , m n ) } называется словом. Слово можно представить в наглядной геометрической форме, если множество имен M интерпретировать точками пространства. Слово W = { (a,1) , (b,1) , (a ,2) , (b,3) } имеет линейную форму и располагается в одномерной целочисленной решетке. Имена клеток являются координатами узлов этой решетки, а узлы помечены символами алфавита А – состояниями клеток. Слово W = { (a, 2,2 ) , (b, 2,3 ) , (c, 3,3 ) , (c, 3,4 ) } располагается в двумерной решетке, как показано на рис. 1. y d 4 3 b 2 a c 1 1 2 3 x Рис. 1. Пример двумерного слова. Далее слова будем представлять помещенными в целочисленную прямоугольную решетку размерности n, n = 1, 2, …. Тогда множество имен можно представить в виде M = N n , где N = {1, 2, …}. Определение 4. Два слова Wi и Wj пересекаются, если в них есть одинаковые клетки (с одинаковыми именами и состояниями) и множество Wi Wj является словом. Определение 5. Два слова Wi и Wj равны, если для каждой клетки слова Wi найдется точно такая же клетка в слове Wj и слова Wi и Wj состоят из одинакового количества клеток. Определение 6. Слово Wi входит в слово Wj , если для каждой клетки слова Wi найдется точно такая же клетка в слове Wj и слово Wi состоит из такого количества клеток, что оно меньше или равно количеству клеток в слове Wj . Определение 7. Процесс поиска вхождений слова Wi в слове Wj называется сопоставлением. Поиск всех непересекающихся вхождений слова Wi в слове Wj называется глобальным сопоставлением. Для формулирования задачи сопоставления с двумерным образцом шаблон представим в виде списка клеток в локальной прямоугольной системе координат V = { (a 1 , x 1 , y1 ) , (a 2 , x 2 , y 2 ) , …, (a d , x d , y d ) }, где a i A (i = 1, d ), обрабатываемое слово представим перечислением P R клеток прямоугольной матрицы W = { (b1,1 , 1,1 ) , (b 2,1 , 2,1 ) , …, (b p ,1 , p,1 ) , (b1, 2 , 1,2 ) , (b 2, 2 , 2,2 ) , …, (b p , 2 , p,2 ) , …., (b1,r , 1, r ) , (b 2,r , 2, r ) , …, (b p ,r , p, r ) }, где a i , j A (i = 1, p , j = 1, r ). Задача сопоставления образца V и слова W состоит в поиске двухкоординатных позиций вхождения V в слово W. Будем называть буквы (a i , x i , y i ) образца V, координаты y i которых равны, столбцом образца, буквы (a j , x j , y j ) образца V, координаты x j которых равны, строкой. Обозначим через m – максимальный индекс столбца образца, через n – максимальный индекс строки образца, количество букв образца в j-й строке через f j , количество букв образца в i-м столбце через g i , максимальный индекс буквы образца в j-й строке через x max , минимальный индекс в j-й строке через x min , j j максимальный индекс буквы образца в i-ом столбце через yimax , минимальный индекс в i-м столбце через y imin . Введенные обозначения рассмотрим для образца V = { (b, 1,1 ) , (b, 2,1 ) , (c, 3,1 ) , (d, 2,2 ) , (a, 3,2 ) , (a, 2,3 ) , (a , 3,3 ) }, изображенного на рис. 2. 1 2 3 b b c 2 d a 3 a a 1 x y Рис. 2. Пример двумерного образца V в локальной прямоугольной системе координат Для двумерного образца V: n = 3, m = 3, f 1 =3, f 2 =2, f 3 =2, g 1 =1, g 2 =3, g 3 =3, =2, x max =3, x 3min =2, x 3max =3, y1min =1, y1max =1, y min =1, y max =3, y 3min =1, x1min =1, x1max =3, x min 2 2 2 2 y3max =3. Также мы будем полагать, что существует способ получения буквы образца (обрабатываемого слова) по координатам x, y, и будем рассматривать образцы, столбцы (строки) которых представляют собой слова, не содержащие пробелов. 2. ПРЯМОЙ ПОДХОД К СОПОСТАВЛЕНИЮ Поиск вхождения двумерного образца начинается с сопоставления обрабатываемого слова с 1-й строкой образца. При успешном результате сопоставления необходимо сопоставить 2-ю строку образца с соответствующей подстрокой следующей строки обрабатываемого слова и т.д., пока не будут успешно сопоставлены все строки образца или не будет достигнут конец строки обрабатываемого слова. При обнаружении отвергающего символа (символ образца называется отвергающим, если в процессе сопоставления он не совпал с очередным символом обрабатываемого слова; с тем же основанием отвергающим называется и соответствующий символ обрабатываемого слова) процесс сопоставления с двумерным образцом снова начинается с поиска вхождения 1-й строки образца в позиции на единицу большей позиции обнаружения частичного вхождения. Если вхождение образца при просмотре слова слева направо обнаружить не удалось, выполняется поиск вхождения образца со следующей строки слова и т. д., пока не будет обнаружено вхождение или не будет достигнута последняя строка обрабатываемого слова. При каждой новой итерации построчного сопоставления образца с соответствующими буквами обрабатываемого слова сравниваются не более n f j1 j символов, так что суммарное количество проверок при сканировании образца в горизонтальном направлении относительно одной фиксированной строки n обрабатываемого слова не превосходит (p m 1) f j . Тогда общее количество j1 проверок при сканировании образца в горизонтальном направлении по всем строкам n обрабатываемого слова не превосходит (r n 1)(p m 1) f j . Количество j1 сравнений максимально, когда отвергающим символом является буква образца с координатами (m, y max . m ) Однако на практике подобные ситуации встречаются редко. Средняя n эффективность равна O(r p f j ) , так как отвергающие символы, как правило, j1 приходятся не на последнюю букву последней строки образца, а гораздо раньше. Очевидно, что реальная эффективность прямого подхода к сопоставлению зависит от реальных свойств – как двумерного образца, так и обрабатываемого слова. Алгоритм, реализующий прямой подход, приведен на рис. 3. j := 1; t := 1; sb := 0; tb := 0; while ( (tb <= r – n) и (sb <= p - m) ) { while ((sb <= p - m) и (j <= n) ) { i = Xminj; s = sb + i while ( i <= Xmaxj ) { if (A(i, j) == B(s, t) ) { i := i + 1; s := s + 1; } else { // несовпадение sb := sb + 1; j := 1; continue 2; // Продолжаем внешний цикл } } j := j + 1; t := t + 1; } if (j > n) { // проверка успешности сопоставления // Область вхождения (sb+1, tb+1)-(sb+1+m, tb+1+n) break; } j := 1; sb := 0; tb := tb + 1; } достижении Прежде чем перейти к рассмотрению В предлагаемом алгоритме образец движется вдоль прямоугольной матрицы обрабатываемого слова слева направо до ее правой границы, однако фактическое сравнение символов выполняется начиная с букв самого правого столбца образца. При успешном сопоставлении букв образца самого правого столбца в порядке снизу вверх выполняется сопоставление предыдущего столбца снизу вверх и т.д. При достижении правой границы обрабатываемого слова процесс сканирования рестартует с левой границы слова и со смещением на одну строку вниз. Первыми таким образом сравниваются символы A(m, Ymmax ) и B(s+m,t+ Ymmax ). Если они не совпадают и B(s+m,t+ Ymmax ) не встречается среди букв Ymmax строки образца, то можно сдвинуть образец по горизонтали на ( X max - X min ) позиций вправо, т.к. Y Y max m max m можно быть уверенным, что ни одна из начинающихся с одной из первых ( X max Y max m ) позиций подстрок (t+ Ymmax ) строки обрабатываемого слова не совпадает с Ymmax X min Y max m строкой образца. Следующими сравниваются A(m, Ymmax ) и B(s+fm+m,t+ Ymmax ). При обнаружении отвергающих символов A(m, j), где Ymmin <= j <= Ymmax и B(s+m,t+j), и при отсутствии среди букв j строки образца буквы B(s+m,t+j), образец сдвигается по горизонтали на f j позиций вправо. Пусть отвергающими оказались символы A(m, Ymmax ) и B(k,l). Как уже говорилось, если B(k,l) не содержится нигде в Ymmax строке образца, шаблон можно сдвинуть на f Ymmax позиций вправо. С другой стороны, если B(k,l) присутствует в образце, и A(mv, Ymmax ) – его самое правое вхождение в Ymmax строке, то образец можно сдвинуть лишь на v позиций вправо, совмещая A(m-v, Ymmax ) с B(k,l). Поиск можно продолжить сравнением A(m, Ymmax ) с B(k+v,l), то есть индекс отвечающий за движение в горизонтальном направлении по обрабатываемому слову увеличиваем на v. Если A(m, Ymmax ) и B(k,l) совпадают, нужно сравнивать все символы в m столбце образца и с соответствующими символами k столбца обрабатываемого слова, пока весь подстолбец обрабатываемого слова не будет сопоставлен со столбцом образца или пока не встретится несовпадение. Когда вхождение m столбца будет определено, необходимо перейти к сопоставлению m-1 столбца образца с соответствующими символами k-1 столбца обрабатываемого слова и т.д. Если отвергающим оказался, скажем, символ A(i, j), то мы знаем, что суффикс j-й строки образца A(i+1,j)… A(Xmaxj,j) равен подстроке обрабатываемого слова B(kXmaxj +i+1, l)… B(k, l), и A(i, j) не равен B(k- Xmaxj +i, l). Теперь, если самым правым вхождением B(k- Xmaxj +i, l) в j строку образца снова является, скажем, A(Xmaxj -v, j), образец можно сдвинуть по горизонтали на i- Xmaxj +v символов вправо, так что A(Xmaxj -v, j) окажется на одной позиции с B(k- Xmaxj +i, l). Процедуру поиска следует продолжить сравнением A(m, Ymmax ) с соответствующим символом, в данном случае с B(k + i- Xmaxj +v, l). Приращение индекса отвечающего за движение в горизонтальном направлении по обрабатываемому слову с позиции несовпадения до следующей пробной позиции равно, таким образом, (k + i- Xmaxj +v)-( k- Xmaxj +i) = v. Заметим, что приращение тоже, что и в случае обнаружения отвергающего символа в самом правом столбце образца. Если A(Xmaxj -v, j) находится правее A(i, j), то значение i- Xmaxj +v отрицательно и совмещение A(Xmaxj -v, j) с B(k + i- Xmaxj +v, l) оказывается излишним, поскольку повлечет за собой шаг назад. В этих обстоятельствах образец лучше сдвинуть на одно место вправо и сравнивать A(m, Ymmax ) с B(k+1, l). Для этого следует увеличить индекс отвечающий за движение в горизонтальном направлении по обрабатываемому слову на (k+1)-( k- Xmaxj +i) = Xmaxj +1-i. Приращения v, используемые для перемещения по обрабатываемому слову в горизонтальном направлении, вычисляются заранее для каждой строки образца отдельно и хранятся в таблицах delta[n]. В процессе поиска доступ к таблице j строке образца delta[j] осуществляется по отвергающим символам обрабатываемого слова, поэтому размер каждой таблицы равен мощности используемого алфавит символов. При формировании таблицы delta[j] вход для символа w равен fj-i, где A(i, j) – самое правое вхождение w в j строку образца, и равен fj, если w не содержится в j строке образца, то есть: delta[j][w] = min {v : v = fj или (0 <=v < fj и A(Xmaxj-v, j) = w)} Таблица delta[j] для алфавита ОМЕГА инициализируется следующим образом: for j = 1 to n do for w = 1 to ОМЕГА delta[j][w] = fj for j = 1 to n do for i = Xminj to Xmaxj delta[j][A(i, j)] = Xmaxj – i Отсюда видно, что время инициализации n таблиц delta равно O(n(ОМЕГА+fj)). Проиллюстрируем работу одной таблицы delta для строки образца x = ABCDB. w A B C D E F G H ... delta[w] 4 0 2 1 5 5 5 5 ... Несовпадение возникает при yi = A x - образец A B C D B y - текст . . . L M N A B C D B . . . i Следующими сравниваются символы xm и yi+skip[A], то есть yi+4. образец текст A B C D B . . . L M N A B C D B . . . i i+4 Ниже приведен алгоритм сопоставления двумерного образца с прямоугольной матрицей символов – обрабатываемое слово. i = m; s = m; tb := 0; // Глоб. индекс смещения в верт.направлении по обрабатываемому слову while ( tb <= r - n ) { while ( (s >0) и (i > 0) и (s <= p) ) { j = Ymaxi; t = tb + j // сканирование i столбца образца в направлении снизу вверх while ( (t > 0) и (j >= Ymini) ) { if (A(i, j) == B(s, t) ) { j: = j – 1; t:= t – 1; } else { // несовпадение if (i > delta[j][B(s, t)] ) { s := fj+1-i; } else { s := s + delta[j][B(s, t)]; } i = m; continue 2; // Продолжаем внешний цикл } } // Переход к сканированию предыдущего столбца образца i := i –1; s := s – 1; } if ( i < 1 ) { // Проверка успешности сопоставления // Область вхождения (s+1, tb+1)-(s+1+m, tb+1+n) break; } // Переход к следующей строке сканирования обрабатываемого слова i := m; s := m; tb := tb + 1; }