Алгоритм Райта — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Новая страница: «'''Алгоритм Райта''' - алгоритм поиска подстроки в строке, который опубликовал Тим Райта в 1...»)
 
Строка 1: Строка 1:
'''Алгоритм Райта''' - алгоритм поиска подстроки в строке, который опубликовал Тим Райта в 1991 году, являющийся модификацией [[Алгоритм Бойера-Мура|алгоритма Бойера-Мура]] и улучшающий его асимптотику
+
'''Алгоритм Райта''' {{---}} алгоритм поиска подстроки в строке, который опубликовал Тим Райта в 1991 году, являющийся модификацией [[Алгоритм Бойера-Мура|алгоритма Бойера-Мура]] и улучшающий его асимптотику
  
 
==Описание алгоритма==
 
==Описание алгоритма==
 +
Алгоритм Райта ищет образец <tex>x</tex> в заданном тексте <tex>y</tex> сравнивания их символы. Сравнение происходит в следующем порядке (окном текста  <tex>y</tex> будем называть последовательность символов <tex>i \dots m - i + 1</tex>, где <tex>m</tex> {{---}} длина образца <tex>x</tex>):
  
 +
# '''Последний''' символ образца сравнивается с самым '''правым''' символом окна.
 +
# Если они совпадают, то '''первый''' символ сравнивается с самым '''левым''' символом окна.
 +
# Если они опять совпали, то сравниваются символы, находящиеся по середине образца и окна.
 +
 +
Если все шаги прошли успешно, то начинаем сравнивать образец и текст посимвольно в обычном порядке, начиная с второго с конца символа. В противном случае, выполняем функцию сдвига плохого символа, которая обрабона в стадии препроцессинга. Эта функция аналогична той, которая была использована в фазе препроцессинга [[Алгоритм Бойера-Мура|алгоритма Бойера-Мура]].
 +
 +
==Псевдокод==
 +
 +
  '''void''' RAITA('''char'''[] x, '''int''' m, '''char'''[] y, '''int''' n) {
 +
      '''int'''[] bmBc
 +
      '''char''' c, firstCh, middleCh, lastCh;
 +
      '''if''' (m == 0)
 +
        '''return'''
 +
      '''else if''' (m == 1) {
 +
        <font color=green>//Проверка на случай поиска вхождения одного символа</font>
 +
        '''int''' match = 0
 +
        '''while''' (match < n) {
 +
            match = findFirst(y, match, n - 1, x[0])
 +
            '''if''' (match != -1) {
 +
              '''print'''(match)
 +
            }
 +
            '''else'''
 +
              '''print'''(<font color=green>"No matches"</font>)
 +
            '''return'''
 +
        }
 +
      }
 +
      '''int''' findFirst('''char'''[] y, '''int''' fromIndex, '''int''' toIndex, '''char''' symbol){
 +
        '''for''' (i = fromIndex .. toIndex){
 +
            '''if''' (y[i] == symbol){
 +
                '''return''' i
 +
            }
 +
        }
 +
        '''return''' -1
 +
      }
 +
      '''boolean''' restEquals('''char'''[] y, '''int''' fromIndex, '''char'''[] x, '''int''' toIndex){
 +
        '''for''' (i = fromIndex .. toIndex){
 +
            '''if''' (y[i] != x[i - fromIndex + 1]){
 +
                '''return''' false
 +
            }
 +
        }
 +
        '''return''' true
 +
      }
 +
    <font color=green> //Стадия препроцессинга</font>
 +
      '''int'''[] preBmBc('''char'''[] x, '''int''' m) {
 +
        '''int'''[] result = '''int'''[m]
 +
        '''for''' (i = 0 .. m - 1){
 +
          result[i] = m;
 +
        }
 +
        '''for''' (i = 0 .. m - 2){
 +
          result[x[i]] = m - i - 1;
 +
        }
 +
        '''return''' result
 +
      }
 +
      bmBc = preBmBc (x, m)
 +
      firstCh = x[0];
 +
      middleCh = x[m/2];
 +
      lastCh = x[m - 1];
 +
      <font color=green>//Поиск</font>
 +
      '''int''' j = 0
 +
      '''while''' (j <= n - m) {
 +
        c = y[j + m - 1]
 +
        '''if''' (lastCh == c && middleCh == y[j + m / 2] && firstCh == y[j] &&
 +
            restEquals(y, j + 1, x, j + m - 2)){
 +
            '''print'''(j)
 +
            '''return'''
 +
        }
 +
        j += bmBc[c];
 +
      }
 +
      '''print'''(<font color=green>"No matches"</font>)
 +
  }
 +
 +
==Асимптотика==
 +
 +
==Пример==
  
 
==Источники информации==
 
==Источники информации==

Версия 00:12, 19 марта 2016

Алгоритм Райта — алгоритм поиска подстроки в строке, который опубликовал Тим Райта в 1991 году, являющийся модификацией алгоритма Бойера-Мура и улучшающий его асимптотику

Описание алгоритма

Алгоритм Райта ищет образец [math]x[/math] в заданном тексте [math]y[/math] сравнивания их символы. Сравнение происходит в следующем порядке (окном текста [math]y[/math] будем называть последовательность символов [math]i \dots m - i + 1[/math], где [math]m[/math] — длина образца [math]x[/math]):

  1. Последний символ образца сравнивается с самым правым символом окна.
  2. Если они совпадают, то первый символ сравнивается с самым левым символом окна.
  3. Если они опять совпали, то сравниваются символы, находящиеся по середине образца и окна.

Если все шаги прошли успешно, то начинаем сравнивать образец и текст посимвольно в обычном порядке, начиная с второго с конца символа. В противном случае, выполняем функцию сдвига плохого символа, которая обрабона в стадии препроцессинга. Эта функция аналогична той, которая была использована в фазе препроцессинга алгоритма Бойера-Мура.

Псевдокод

  void RAITA(char[] x, int m, char[] y, int n) {
     int[] bmBc
     char c, firstCh, middleCh, lastCh;
     if (m == 0)
        return
     else if (m == 1) {
        //Проверка на случай поиска вхождения одного символа
        int match = 0
        while (match < n) {
           match = findFirst(y, match, n - 1, x[0])
           if (match != -1) {
              print(match)
           }
           else
              print("No matches")
           return
        }
     }
     int findFirst(char[] y, int fromIndex, int toIndex, char symbol){
        for (i = fromIndex .. toIndex){
           if (y[i] == symbol){
               return i
           }
        }
        return -1
     }
     boolean restEquals(char[] y, int fromIndex, char[] x, int toIndex){
        for (i = fromIndex .. toIndex){
           if (y[i] != x[i - fromIndex + 1]){
               return false
           }
        }
        return true
     }
     //Стадия препроцессинга
     int[] preBmBc(char[] x, int m) {
        int[] result = int[m]
        for (i = 0 .. m - 1){
     	    result[i] = m;
        }
        for (i = 0 .. m - 2){
     	    result[x[i]] = m - i - 1;
        }
        return result
     }
     bmBc = preBmBc (x, m)
     firstCh = x[0];
     middleCh = x[m/2];
     lastCh = x[m - 1];
     //Поиск
     int j = 0
     while (j <= n - m) {
        c = y[j + m - 1]
        if (lastCh == c && middleCh == y[j + m / 2] && firstCh == y[j] &&
           restEquals(y, j + 1, x, j + m - 2)){
           print(j)
           return
        }
        j += bmBc[c];
     }
     print("No matches")
  }

Асимптотика

Пример

Источники информации