POJ—3461 Oulipo

版权声明:请联系[email protected] https://blog.csdn.net/wanglin007/article/details/84400569

Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 50449Accepted: 20017DescriptionThe 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 Input3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIANSample Output1
3
0SourceBAPC 2006 Qualification

#include<iostream>
#include<cstring>
#include<cstdio>
//用cin会超时 
using namespace std;
void get_next(char T[],int next[])
{
	 int i=0,k=-1,l=strlen(T);
	 next[0]=-1;
	 //开头的标记为了使下一个i++的值等于0,将可能的前缀和后缀相等的最大长度等于的0赋值给第i+1的位置上 
	 while(i<l)
	 {
		  if(T[i]==T[k]||k==-1)
		   next[++i]=++k;
		  //i前的字符串的后缀和前缀相等时的前缀的下一个字符的下标 
		  else 
		   k=next[k];
		  //将k退回到下标为k上的next值,就是让上面的if内容变成下标为i+1和下标为next【k】的判断 
	 }
}
int KMP(char ma[],char T[],int next[])
{
	 int i=0,j=0,ans=0,l1=strlen(ma),l2=strlen(T);
	 while(i<l1&&j<l2)
	 {
		  if(ma[i]==T[j]||j==-1){i++;j++;}
		  //如果j=-1说明模式串与主串无匹配,如果相等说明i和j之前的以模式串为主的部分串是相等的
		  //所以只需要i和j都向下一位移动就行 
		  else{j=next[j];}
		  //说明模式串第j上的字符与主串上的第i上的不符,只需要将j跳到next【j】上就行了,
		  //因为在get_next时已经判断每一个位子上如果失配需要跳到什么位子了 
		  if(j==l2){j=next[j];ans++;}
		  //由于j跳越,会覆盖且都有模式串的可能 
	 }
	 return ans;
}
int main()
{
	 int N,*next;
	 char ma[1000050],T[1000050];
	 scanf("%d",&N);
	 while(N--)
	 {
		  scanf("%s%s",&T,&ma);
		  next=new int[strlen(T)+1];
		  get_next(T,next);
		  cout<<KMP(ma,T,next)<<endl;
	 }
	 return 0;
}

猜你喜欢

转载自blog.csdn.net/wanglin007/article/details/84400569
今日推荐