【POJ3461】【KMP】Oulipo
Description
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book:
Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…
Perec would probably have scored high (or rather, low) in the following contest. People are asked to write a perhaps even meaningful text on some subject with as few occurrences of a given “word” as possible. Our task is to provide the jury with a program that counts these occurrences, in order to obtain a ranking of the competitors. These competitors often write very long texts with nonsense meaning; a sequence of 500,000 consecutive 'T's is not unusual. And they never use spaces.
So we want to quickly find out how often a word, i.e., a given string, occurs in a text. More formally: given the alphabet {'A', 'B', 'C', …, 'Z'} and two finite strings over that alphabet, a word W and a text T, count the number of occurrences of W in T. All the consecutive characters of W must exactly match consecutive characters of T. Occurrences may overlap.
Input
The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:
- One line with the word W, a string over {'A', 'B', 'C', …, 'Z'}, with 1 ≤ |W| ≤ 10,000 (here |W| denotes the length of the string W).
- One line with the text T, a string over {'A', 'B', 'C', …, 'Z'}, with |W| ≤ |T| ≤ 1,000,000.
Output
For every test case in the input file, the output should contain a single number, on a single line: the number of occurrences of the word W in the text T.
Sample Input
3 BAPC BAPC AZA AZAZAZA VERDI AVERDXIVYERDIAN
Sample Output
1 3 0
Source
1 /* 2 宋代李之仪 3 卜算子·我住长江头 4 我住长江头,君住长江尾。日日思君不见君,共饮长江水。 5 此水几时休,此恨何时已。只愿君心似我心,定不负相思意。 6 */ 7 #include <iostream> 8 #include <cstdio> 9 #include <algorithm> 10 #include <cstring> 11 #include <vector> 12 #include <utility> 13 #include <iomanip> 14 #include <string> 15 #include <cmath> 16 #include <queue> 17 #include <assert.h> 18 #include <map> 19 #include <ctime> 20 #include <cstdlib> 21 #include <stack> 22 #define LOCAL 23 const int MAXN = 1000000 + 10; 24 const int INF = 100000000; 25 const int SIZE = 450; 26 const int MAXM = 1000000 + 10; 27 const int maxnode = 0x7fffffff + 10; 28 using namespace std; 29 int l1, l2; 30 char a[MAXN], b[MAXN]; 31 int next[20000];//不用开太大了.. 32 void getNext(){ 33 //初始化next数组 34 next[1] = 0; 35 int j = 0; 36 for (int i = 2; i <= l1; i++){ 37 while (j > 0 && a[j + 1] != a[i]) j = next[j]; 38 if (a[j + 1] == a[i]) j++; 39 next[i] = j; 40 } 41 return; 42 } 43 int kmp(){ 44 int j = 0, cnt = 0; 45 for (int i = 1; i <= l2; i++){ 46 while (j > 0 && a[j + 1] != b[i]) j = next[j]; 47 if (a[j + 1] == b[i]) j++; 48 if (j == l1){ 49 cnt++; 50 j = next[j];//回到上一个匹配点 51 } 52 } 53 return cnt; 54 } 55 56 void init(){ 57 scanf("%s", a + 1); 58 scanf("%s", b + 1); 59 l1 = strlen(a + 1); 60 l2 = strlen(b + 1); 61 } 62 63 int main(){ 64 int T; 65 66 scanf("%d", &T); 67 while (T--){ 68 init(); 69 getNext(); 70 printf("%d\n", kmp()); 71 } 72 /*scanf("%s", a + 1); 73 l1 = strlen(a + 1); 74 getNext(); 75 for (int i = 1; i <= l1; i++) printf("%d ", next[i]);*/ 76 return 0; 77 }