Int needle len = strlen(needle)
Вид материала | Документы |
- Системa Неинвазивной Мезотерапии™ аппараты btl-4000 nnm и btl-5000 nnm, 135.99kb.
- Конспект третьей лекции Метод Main может иметь четыре формата int Main() без параметров, 58.05kb.
- Полезные ссылки по теме, 9.51kb.
- Решает предложить будущим компетентным всемирным конференциям радиосвязи, 624kb.
- 197755 г. Санкт-Петербург, п. Лисий Нос, ул. Новоцентральная дом 21 Т/ф: (812) 434-93-63., 24.09kb.
- Vogue 4 Цвет кузова: Bournville (коричневый) Цвет салона: Arabica Ox Lthr Seat, Arabica/Ivory, 59.85kb.
- Еживают пик или спад сезона гриппа в северном полушарии, но при этом активная циркуляция, 104.44kb.
- Тезисы выступления на конференции «Адвокатская тайна», 172.58kb.
- В. М. Казиев Об арифметических возможностях компьютера и компьютерных возможностях, 78.22kb.
- 8. Указатели. Указатель это переменная, содержащая адрес другой переменной, 143.78kb.
int mystrcmp(const char *a, const char *b){
while ( *a && *b && *a == *b )
++a, ++b;
return *a - *b;}
char *strstr (const char *s1,
char *s2)
{
int n;
n = strlen(s2);
for ( ; ;) {
s1 = strchr(s1, s2[0]);
if (s1 == NULL)
return NULL;
if (strncmp (s1, s2, n) == 0)
return (char *) s1;
s1++;
}
}
int boyer_moore(const char * haystack, const char * needle)
{
int i, j, k;
int needle_table[256];
int needle_len = strlen(needle);
int haystack_len = strlen(haystack);
if (needle_len < haystack_len then)
{
for (i = 0; i < 256; i++)
needle_table[i] = needle_len;
for (i = 1; i < needle_len; i++)
needle_table[needle[i]] = needle_len-i;
i = needle_len;
j = i;
while ((j > 0) && (i <= haystack_len))
{
j = needle_len;
k = i;
while ((j > 0) && (haystack[k] = needle[j]))
{
k--;
j--;
}
i += needle_table[haystack[i]];
}
if (k > haystack_len - needle_len then)
return 0;
else
return k + 1;
}
else
return 0;
}
Алгоритм Бойера — Мура
Описание алгоритма
Первым делом строится таблица смещений для искомого шаблона. Совмещается начало текста (строки) и шаблона, проверка начинается с последнего символа шаблона. Если последний символ шаблона и соответствующий ему при наложении символ строки не совпадают, то образец сдвигается относительно строки на величину, полученную из таблицы смещений. Причем берем символ из строки(а не шаблона) и смотрим соответствующий сдвиг в таблице. Сдвигаем и снова начинаем проверку с последнего символа. Если же символы совпадают, производится сравнение предпоследнего символа шаблона и т. д. Если все символы шаблона совпали с наложенными символами строки, значит мы нашли подстроку и поиск окончен. Если же какой-то (НЕ ПОСЛЕДНИЙ) символ шаблона не совпадает с соответствующим символом строки, мы сдвигаем шаблон на ОДИН символ вправо и снова начинаем проверку с последнего символа. Весь алгоритм выполняется до тех пор, пока либо не будет найдено вхождение искомого образца, либо не будет достигнут конец строки.
Алгоритм Кнута-Морриса-Пратта
Этот алгоритм был получен благодаря глубокому анализу алгоритма Морриса-Пратта. Итак, посмотрим, что еще можно сделать, чтобы увеличить размер сдвига.
Рассмотрим сравнение на позиции i, где образец x[ 0, m - 1 ] сопоставляется с частью текста y[ i, i + m - 1 ]. Предположим, что первое несовпадение произошло между y[ i + j ] и x[ j ] , где 1 < j < m. Тогда y[ i, i + j - 1 ] = x[ 0, j - 1 ] = u и a = y[ i + j ] =/= x[ j ] = b.
При сдвиге вполне можно ожидать, что префикс образца u сойдется с каким-нибудь суффиксом подслова текста u. Более того, если мы хотим избежать выявления другого несовпадения ( то есть не тратить на это операцию сравнения ;-) ), буква, находящаяся за префиксом v в образце должна отличаться от b. Наиболее длинный такой префикс v называется границей u ( он встречается по обоим сторонам u ).
Это приводит к следующему алгоритму: пусть kmp_next[ j ] - длина длиннейшей границы x[ 0, j - 1 ], за которой следует символ c, отличающийся от x[ j ]. Тогда после сдвига мы можем возобновить сравнения между символами y[ i + j ] и x[ j - kmp_next[ j ] ] без возможной потери местонахождения образца. Таблица kmp_next может быть вычислена за O( m ) перед поиском через применение этого же алгоритма поиска к самому образцу ( т.е y = x ). При этом максимальное количество сравнений для одного символа текста - logФ( m ), где Ф - золотое сечение: ( корень из 5 + 1 ) / 2.
void PRE_KMP( char *x, int m, int kmp_next[] ) {
int i, j;
i=0;
j=kmp_next[0]=-1;
while ( i < m ) {
while ( j > -1 && x[ i ] != x[ j ] ) j=kmp_next[ j ];
i++;
j++;
if ( x[ i ] == x[ j ] ) kmp_next[i]=kmp_next[j];
else kmp_next[ i ] = j;
}
}
void KMP( char *x, char *y, int n, int m ) {
int i, j, kmp_next[XSIZE];
/* Preprocessing */
PRE_KMP(x, m, kmp_next );
/* Searching */
i=j=0;
while ( i < n ) {
while ( j > -1 && x[ j ] != y[ i ] ) j = kmp_next[ j ];
i++;
j++;
if ( j >= m ) {
OUTPUT( i - j );
j = kmp_next[ j ];
}
}
}