解题关键:1、直接套kmp模板即可,注意最后输出的位置,需要在索引的位置+1。
2、next用作数组名在oj中会编译错误,
3、选用g++,只有g++才会接受bits/stdc++.h
OJ中g++和c++的区别:
1、输出double类型时,如果采用G++提交,scanf采用%lf,printf采用%f,否则会报错
2、使用GCC/G++的提醒:
对于64位整数, long long int 和 __int64 都是支持并且等价的.但是在读和写的时候只支持scanf("%
I64d", ...)和printf("%I64d", ...).
不支持"%lld"是因为MinGW下的GCC和G++使用的msvcrt.dll动态链接库并不支持C99标准.
根据ISO C++标准,在G++下,main函数的返回值必须是int,否则将会导致Compile Error(编译错误)的判答
3、G++/GCC使用scanf、printf时注意引用<stdio.h>,只引用<iostream>不识别
1 #include<bits/stdc++.h> 2 #define N 1000002 3 using namespace std; 4 typedef long long ll; 5 int Next[N]; 6 int s[N],t[N]; 7 int slen,tlen; 8 int n,m; 9 void getNext(){ 10 int i=0,j=-1; 11 Next[0]=-1; 12 while(i<tlen){ 13 if(j==-1||t[i]==t[j]) Next[++i]=++j; 14 else j=Next[j]; 15 } 16 } 17 int kmp(){ 18 getNext(); 19 int i=0,j=0; 20 while(i<slen&&j<tlen){ 21 if(j==-1||s[i]==t[j]) ++i,++j; 22 else j=Next[j]; 23 } 24 if(j==tlen) return i-j+1; 25 else return -1; 26 } 27 int main(){ 28 ios::sync_with_stdio(0); 29 int tt; 30 cin>>tt; 31 while(tt--){ 32 int n,m; 33 cin>>n>>m; 34 for(int i=0;i<n;i++){ 35 cin>>s[i]; 36 } 37 for(int i=0;i<m;i++){ 38 cin>>t[i]; 39 } 40 slen=n; 41 tlen=m; 42 cout<<kmp()<<endl; 43 } 44 }
1 #include<bits/stdc++.h> 2 #define N 1000000 3 using namespace std; 4 typedef long long ll; 5 char s[N],t[N]; 6 int Next[N]; 7 int slen,tlen; 8 void getNext(){ 9 int i=0,j=-1;//注意写next数组时j为-1 10 Next[0]=-1; 11 while(i<tlen){ 12 if(j==-1||t[i]==t[j]) Next[++i]=++j; 13 else j=Next[j]; 14 } 15 } 16 int kmp_index(){ 17 getNext(); 18 int i=0,j=0; 19 while(i<slen&&j<tlen){ 20 if(j==-1||s[i]==t[j]) i++,j++; 21 else j=Next[j]; 22 } 23 if(j==tlen) return i-j; 24 else return -1; 25 }
1 int kmp_count(){ 2 int ans=0,i=0,j=0; 3 getNext(); 4 for(i=0;i<slen;i++){ 5 while(j>0&&s[i]!=t[j]) j=Next[j]; 6 if(s[i]==t[j]) j++; 7 if(j==tlen){ 8 ans++; 9 j=Next[j]; 10 } 11 } 12 return ans; 13 }