HDU 2087
Ideas:
Cut the flower step.
In fact, after matching is completed, we can make j = 1. (Note that my next array is different from that of ordinary people. My next [1] = 0) in this way, the matching will continue at the next position.
AC Program:
# Include <vector> # include <list> # include <map> # include <set> # include <queue> # include <deque> # include <stack> # include <bitset> # include <algorithm> # include <functional> # include <numeric> # include <utility> # include <sstream> # include <iostream> # include <iomanip> # include <cstdio> # include <cmath> # include <cstdlib> # include <cstring> # include <ctime> # include <queue> # include <cassert> typedef long ll; # defineclr (a) memset (a), 0, sizeof (a) # definerep (I, a, B) for (int I = (); I <(int) (B); I ++) # defineper (I, a, B) for (int I = (a)-1 ); I >=( int) (B); I --) # defineinf (0x7fffffff) # defineeps1e-6 # defineMAXN # define MODN (1000000007) using namespace std; int next [1000]; char s [1000], t [1000]; int num; void get_next () {int len1 = strlen (t + 1 ); // The int j = 1; int k = 0; next [1] = 0; while (j <= len1) {if (k = 0 | t [j] = t [k]) // k is similar to the definition of k in books {j ++; k ++; next [j] = k;} else {k = next [k] ;}} void kmp () {int len1 = strlen (s + 1 ); int len2 = strlen (t + 1); int j = 1; int I = 1; for (; I <= len1 & j <= len2 ;) // if separated by commas, the link is or {if (s [I] = t [j]) {I ++; j ++; if (j> len2) {j = 1; num ++ ;}} else {j = next [j]; if (j = 0) {I ++; j ++ ;}}}} int main () {while (cin> s + 1) {if (s [1] = '#') break; cin> t + 1; get_next (); num = 0; kmp (); cout <num <endl ;}; // system ("pause"); return 0 ;}
HDU 1686 question: how many times can a mode string be matched at most in the parent string, including overlap
Ideas:
In fact, the basic next array definition is used: after the current match is complete, it is assumed that the next position is not matched.
For example:
AZA
AZAZAZA
Why? Why not assume that one of ZA following AZA is not mismatched?
This is what next [n + 1] means the maximum equality between the prefix and suffix of the entire string.
If n + 1 is not matched, next [n + 1] will move the corresponding number of steps to match the original string based on the prefix and suffix that you have compared with yourself.
AZAZAZA
***
AC Program:
# Include <vector> # include <list> # include <map> # include <set> # include <queue> # include <deque> # include <stack> # include <bitset> # include <algorithm> # include <functional> # include <numeric> # include <utility> # include <sstream> # include <iostream> # include <iomanip> # include <cstdio> # include <cmath> # include <cstdlib> # include <cstring> # include <ctime> # include <queue> # include <cassert> typedef long ll; # defineclr (a) memset (a), 0, sizeof (a) # definerep (I, a, B) for (int I = (); I <(int) (B); I ++) # defineper (I, a, B) for (int I = (a)-1 ); I >=( int) (B); I --) # defineinf (0x7fffffff) # defineeps1e-6 # defineMAXN # define MODN (1000000007) using namespace std; int next [100005]; char s [1000005], t [10005]; int num; void get_next () {int len1 = strlen (t + 1 ); // The int j = 1; int k = 0; next [1] = 0; while (j <= len1) {if (k = 0 | t [j] = t [k]) // k is similar to the definition of k in qingshu. {j ++; k ++; next [j] = k;} else {k = next [k] ;}} void kmp () {int len1 = strlen (s + 1 ); int len2 = strlen (t + 1); int j = 1; int I = 1; for (; I <= len1 & j <= len2 ;) // if separated by commas, the link is or {if (s [I] = t [j]) {I ++; j ++; if (j = len2 + 1) {j = next [j]; // Hahahaha, finally understand that it is still the most basic KMP, only the value of the last next array in the substring is searched. num ++ ;}} else {j = next [j]; // next [n] is an array that can be used to obtain the maximum equal value of the prefix and suffix of a string whose n + 1 is not fit, // However, when searching for substrings, n is the most out-of-match position, and n is the array with the same prefix and suffix as the maximum value.} if (j = 0) // when it is equal to 0, it is the first position mismatch. In this way, you have to move the entire unit {I ++; j ++ ;}} int main () {int test; // cin> test; scanf ("% d", & test); while (test --) {// cin> t + 1> s + 1; scanf ("% s", t + 1, s + 1); // you want to vomit blood, at the beginning, cin times out to get_next ();/* for (int I = 1; I <= 3; I ++) cout <"<next [I]; cout <endl; */num = 0; kmp (); cout <num <endl ;}; // system ("pause"); return 0 ;}