[The KMP] String Matching

String match

Description [title]

For the size of a character set C character string PP , may be any two characters in the p position interchanging, e.g. p = 12321 , exchange 1 , 21 , 2 to obtain 21312 , exchange 1 , 4 to obtain 42,324 , can exchange any number of times. If the exchange of p into a string of q , to the q and p are matched.

Given the size of two character sets C string s , t , to obtain s the number of contiguous substrings have t match.

[Enter]

The first line of two integers T , C , respectively, and the number of data sets the size of characters, characters . 1 ~ C integers represented.

For each set of data: The first line of two integers n- , m , respectively S , T length.

The second line n positive integer S .

The third row m positive integer T .

[Output]

For each test, two output lines comprising:

The first line of a positive integer k , represents s has k consecutive sub strings t match.

The second row from small to large outputs k number indicating s with t match the first string of successive sub index (subscript from 1 starts).

[Sample input]

3 3

6 3

1 2 1 2 3 2

3 1 3

6 3

1 2 1 2 1 2

3 1 3

6 3

1 1 2 1 2 1

3 1 3

[Sample Output]

3

1 2 4

4

1 2 3 4

3

2 3 4

[Agreement] and the size of data

For 10% of the data, to meet the n-, m, C 1000N, m, C 1000 ;

For another 20% of the data, to meet the n-, m 105 , C 40N, m 105 , C 40 ;

For another 30% of the data, to meet the n-, m, C 105n, m, C 105 ;

For 100% data meet . 1 n-, m, C 106 , T = 31 is n-, m, C 106 , T =. 3 .

【analysis】

This is actually a KMP title

The difficulty is how to exchange the title character

We can start an array l [1 ~ c]

L [x] on showing an x position occurring

a [i] representing the character s [i] a distance from appearing on a same character

b [i] represents the character t [i] a distance from appearing on a same character

Then there KMP

Difficulty is determining how to s [i] (t [i ]) than in the pattern string is

Well this is actually very simple

Directly determining a x whether the distance is greater than the occurrence j not on the list

AC [ Code ]

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N (1000000+2)
#define C (1000000+2)
using namespace std;
int p[N];
int a[N],b[N];
int l[C];
int ans[N];
template<typename T>inline void read(T& x){
	char temp=getchar();bool u=0;
	for(x=0;temp<'0'||temp>'9';u=temp=='-',temp=getchar());
	for(;temp>='0'&&temp<='9';x=x*10+temp-'0',temp=getchar());
	if(u)x=-x;
	return ;
}
inline int jdg(int x,int l){return x<l?x:0;}
inline bool eq(int x,int y,int l){return jdg(x,l)==jdg(y,l);}
void work(){
	register int i,j,k;
	register int n,m;
	read(n);
	read(m);
	memset(a,0,sizeof a);
	memset(b,0,sizeof b);
	memset(p,0,sizeof p);
	memset(l,0,sizeof l);
	for(i=1;i<=n;i++){
		read(k);
		a[i]=i-l[k];
		l[k]=i;
	}
	memset(l,0,sizeof l);
	for(i=1;i<=m;i++){
		read(k);
		b[i]=i-l[k];
		l[k]=i;
	}
	for(i=1,j=0;i<m;i++){
		while(j&&!eq(b[i+1],b[j+1],j+1))
			j=p[j];
		if(eq(b[i+1],b[j+1],j+1))
			j++;
		p[i+1]=j;
	}
	for(k=i=j=0;i<n;i++){
		while(j&&!eq(a[i+1],b[j+1],j+1))
			j=p[j];
		if(eq(a[i+1],b[j+1],j+1))
			j++;
		if(j==m){
			ans[++k]=i+2-m;
			j=p[j];
		}
	}
	printf("%d\n",k);
	for(i=1;i<=k;i++)
		printf("%d ",ans[i]);
	putchar('\n');
	return ;
}
int main(){
	register int t,c,i;
	read(t);
	read(c);
	for(i=1;i<=t;i++)
		work();
	return 0;
}

  

Guess you like

Origin www.cnblogs.com/TbIblog/p/11247312.html