Nadesłany przez Tomasz Lubiński, 23 marca 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
bm.c:
// Algorytm Boyer-Moore // Tomasz Lubinski (c) 2007 // www.algorytm.org #include "stdio.h" //size of the alphabet #define ASIZE 255 //max. size of the pattern #define PSIZE 100 //max. size of the text #define TSIZE 1000 #define MAX(a, b) (a > b) ? a : b int bad_character_shift[ASIZE]; int good_suffix_shift[PSIZE]; int suff[PSIZE]; //prepare bad character shift table void pre_bad_character_shift(char *pattern) { int i; int m = strlen(pattern); for (i = 0; i < ASIZE; i++) { bad_character_shift[i] = m; } for (i = 0; i < m - 1; ++i) { bad_character_shift[pattern[i]] = m - i - 1; } } //prepare suff table void pre_suff(char *pattern) { int i, j; int m = strlen(pattern); suff[m - 1] = m; for (i = m - 2; i >= 0; --i) { for (j = 0; j <= i && pattern[i-j] == pattern[m-j-1]; j++); suff[i] = j; } } //prepare good_suffix_shift table void pre_good_suffix_shift(char *pattern) { int i,j; int m = strlen(pattern); pre_suff(pattern); for (i = 0; i < m; i++) { good_suffix_shift[i] = m; } j = 0; for (i = m - 1; i >= 0; --i) { if (suff[i] == i + 1) { for (; j < m - 1 - i; ++j) { good_suffix_shift[j] = m - 1 - i; } } } for (i = 0; i <= m - 2; ++i) { good_suffix_shift[m - 1 - suff[i]] = m - 1 - i; } } //Boyer-Moore algorithm void BM(char *text, char *pattern) { int i, j; int m = strlen(pattern); int n = strlen(text); pre_bad_character_shift(pattern); pre_good_suffix_shift(pattern); j = 0; while (j <= n - m) { for (i = m - 1; i >= 0 && pattern[i] == text[i + j]; --i); if (i < 0) { printf("%d ", j); j += good_suffix_shift[0]; } else j += MAX(good_suffix_shift[i], bad_character_shift[text[i + j]] - m + 1 + i); } } //Get data int main() { char pattern[PSIZE]; char text[TSIZE]; printf("Podaj tekst\n"); scanf("%s", text); printf("Podaj wzorzec\n"); scanf("%s", pattern); BM(text, pattern); }