Code:
#include <iostream> #include <cstring> using namespace std; const int N = 1000100; int n, m; // n main string length, m pattern string length char a[N], b[N]; // a main string, b pattern string, subscripts start at zero int nextt[N]; void get_nextt() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j] ) nextt[++i] = ++j; else j = nextt[j]; } } void get_nextval() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j]) { ++i, ++j; nextt[i] = (b[i] != b[j]) ? j : nextt[j]; } else { j = nextt[j]; } } } int kmp_index(int pos) { // Find the position of the pattern string after the pos position character of the main string int i = pos, j = 0; while(i < n && j < m) { if(-1 == j || a[i] == b[j]) { ++i, ++j; } else { j = nextt[j]; } } if(j >= m) return i-m; else return -1; } int kmp_count(int pos) { // Find how many times the pattern string appears in the main string int i = pos, j = 0; int years = 0; while(i < n) { if(-1 == j || a[i] == b[j]) { ++i, ++j; if(j >= m) { ++ years; j = nextt[j]; } } else j = nextt[j]; } return ans; } intmain() { cin >> a >> b; get_nextt(); get_nextval(); int Index = kmp_index( 0 ); int Count = kmp_count( 0 ); return 0; }
Check it out with two questions:
Number Sequence
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 35581 Accepted Submission(s): 14734
Problem Description
Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.
Input
The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000].
Output
For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.
Sample Input
2 13 5 1 2 1 2 3 1 2 3 1 3 2 1 2 1 2 3 1 3 13 5 1 2 1 2 3 1 2 3 1 3 2 1 2 1 2 3 2 1
Sample Output
6 -1
Code:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 1000100; int n, m; // n main string length, m pattern string length int a[N], b[N]; // a main string, b pattern string, subscripts start at zero int nextt[N]; void get_nextt() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j] ) nextt[++i] = ++j; else j = nextt[j]; } } void get_nextval() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j]) { ++i, ++j; nextt[i] = (b[i] != b[j]) ? j : nextt[j]; } else { j = nextt[j]; } } } int kmp_index(int pos) { // Find the position of the pattern string after the pos position character of the main string int i = pos, j = 0; while(i < n && j < m) { if(-1 == j || a[i] == b[j]) { ++i, ++j; } else { j = nextt[j]; } } if(j >= m) return i-m; else return -1; } int main() { int T; cin >> T; while(T--) { cin >> n >> m; for(int i=0; i<n; i++) { scanf("%d",&a[i]); } for(int i=0; i<m; i++) { scanf("%d",&b[i]); } get_nextval(); int temp = kmp_index(0); if(temp != -1) ++ temp; cout << temp << endl; } return 0; }
2264: sequence
Time Limit: 1 Sec Memory Limit: 128 MBCommits: 578 Resolved: 104
[ Commit ][ Status ][ Discussion Board ][Assert By: admin ]
Topic description
Given a sequence A with n numbers and a sequence B with m (m<=n) numbers.
Ask how many consecutive subsequences of length m A k ,A k+1 ,...,A k+m-1 exist in A such that for any 1<=i, j<=m satisfies Ak+i-1 -B i =A k+j-1 -B j
enter
The first line contains two integers n, m (1 <= m <= n <= 10 6 )
The next line contains n integers describing the sequence A (A i <= 10 9 )
The next line contains m integers describing the sequence B (B i <= 10 9 )
output
output a number to indicate the answer
sample input
7 4
6 6 8 5 5 7 4
7 7 9 6
Sample output
2
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 1000100; int n, m; int a[N], b[N]; int nextt[N]; void get_nextt() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j] ) nextt[++i] = ++j; else j = nextt[j]; } } int kmp_count(int pos) { int i = pos, j = 0; int years = 0; while(i < n) { if(-1 == j || a[i] == b[j]) { ++i, ++j; if(j >= m) { ++ years; j = nextt[j]; } } else j = nextt[j]; } return ans; } int main() { cin >> n >> m; for(int i=0; i<n; i++) scanf("%d",&a[i]); for(int i=0; i<m; i++) scanf("%d",&b[i]); n--, m--; for(int i=0; i<n; i++) a[i] = a[i+1] - a[i]; for(int i=0; i<m; i++) b[i] = b[i+1] - b[i]; /* for(int i=0; i<m; i++) { cout << nextt[i] << " "; } cout << endl;*/ get_nextt(); int ans = kmp_count(0); cout << ans << endl; return 0; }