hdu 1686 Oulipo

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.

InputThe 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.
OutputFor 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

题解:

这道题就是一道模板题,但是我还是出错了T_T

 1 if(k==plen-1)
 2         {
 3             ans++;  //是用来计数的
 4             k=-1;
 5             i=i-plen+1+1;
 6         }
 7 
 8 我让他每次从父字符串找到这个子字符串后就让这个子字符串从头开始在父字符串的上一个匹配成功的位置之后再开始匹配
 9 
10 这样每次都是从头开始匹配,那我们的next数组的作用不就体会不到了吗
11 
12 所以每找到一个子字符串后就利用next进行下一个的寻找

改成

1 if(k==plen-1)
2         {
3             ans++;
4             k=next[k];
5         }

 

最后代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1000005;
 7 const int INF=0x3f3f3f3f;
 8 char str[maxn],ptr[maxn];
 9 int ans;
10 void get_next(int len,int *next)
11 {
12     next[0]=-1;
13     int k=-1;
14     for(int i=1;i<=len-1;++i)
15     {
16         while(k>-1 && ptr[k+1]!=ptr[i])
17             k=next[k];
18         if(ptr[k+1]==ptr[i])
19         {
20             k+=1;
21         }
22         next[i]=k;
23     }
24 }
25 void kmp(int slen,int plen)
26 {
27     int next[plen];
28     get_next(plen,next);
29     int k=-1;
30     for(int i=0;i<slen;++i)
31     {
32         while(k>-1 && ptr[k+1]!=str[i])
33         {
34             k=next[k];
35         }
36         if(ptr[k+1]==str[i])
37         {
38             k=k+1;
39         }
40         if(k==plen-1)
41         {
42             ans++;
43             k=next[k];
44             //i=i-plen+1+1;
45         }
46     }
47 }
48 int main()
49 {
50     int t;
51     scanf("%d",&t);
52     while(t--)
53     {
54         ans=0;
55         scanf("%s%s",ptr,str);
56         int slen=strlen(str);
57         int plen=strlen(ptr);
58         kmp(slen,plen);
59         printf("%d\n",ans);
60     }
61     return 0;
62 }
View Code

 

转载于:https://www.cnblogs.com/kongbursi-2292702937/p/11194997.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值