HDU 1711 Number Sequence(模板题)
#include <cstdio> const int MAXN = 1000010; const int MAXL = 10010; int N, M; int textS[MAXN]; int tarS[MAXL]; int next[MAXL]; void GetNextVal( int* s, int* nextval, int len ) { int i = 0, j = -1; nextval[0] = -1; while ( i < len ) { if ( j == -1 || s[i] == s[j] ) { ++i, ++j; nextval[i] = j; } else j = nextval[j]; } return; } int KMP( int *t, int lent, int *s, int lens ) { GetNextVal( t, next, lent ); int i = 0, j = 0; while ( j < lens ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lent ) return j; } else i = next[i]; } return -1; } int main() { int T; scanf( "%d", &T ); while ( T-- ) { scanf( "%d%d", &N, &M ); for ( int i = 0; i < N; ++i ) scanf( "%d", &textS[i] ); for ( int i = 0; i < M; ++i ) scanf( "%d", &tarS[i] ); int ans = KMP( tarS, M, textS, N ); if ( ans < 0 ) printf( "%d\n", ans ); else printf("%d\n", ans - M + 1 ); } return 0; }
HDU 1686 Oulipo(模板题)
#include <cstdio> #include <cstring> #include <cstdlib> const int MAXN = 1000010; const int MAXL = 10010; char tarS[MAXL]; char testS[MAXN]; int next[MAXL]; void GetNextVal( char *s, int len, int *p ) { int i = 0, j = -1; p[0] = -1; while ( i < len ) { if ( j == -1 || s[i] == s[j] ) { ++i, ++j; p[i] = j; } else j = p[j]; } return; } int KMP( char *t, char *s ) { int cnt = 0; int lent = strlen(t); int lens = strlen(s); GetNextVal( t, lent, next ); int i = 0, j = 0; while ( j < lens ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lent ) { ++cnt; i = next[i]; } } else i = next[i]; } return cnt; } int main() { int T; scanf( "%d", &T ); while ( T-- ) { scanf( "%s%s", tarS, testS ); printf("%d\n", KMP( tarS, testS ) ); } return 0; }
HDU 2203 亲和串
#include <cstdio> #include <cstring> #include <cstdlib> const int MAXN = 100010; char testS[ MAXN << 1 ]; char tarS[MAXN]; char temp[MAXN]; int next[MAXN]; void GetNextVal( char *s, int len, int *p ) { int i = 0, j = -1; p[0] = -1; while ( i < len ) { if ( j == -1 || s[i] == s[j] ) { ++i, ++j; p[i] = j; } else j = p[j]; } return; } bool KMP( char *s, int lenS, char *t, int lenT ) { GetNextVal( t, lenT, next ); int i = 0, j = 0; while ( j < lenS ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lenT ) return true; } else i = next[i]; } return false; } int main() { while ( ~scanf( "%s", temp ) ) { scanf("%s", tarS ); int lenS = strlen(temp); int lenT = strlen(tarS); if ( lenT > lenS ) { puts("no"); continue; } strcpy( testS, temp ); strcpy( &testS[lenS], temp ); KMP( testS, lenS + lenS, tarS, lenT ) ? puts("yes") : puts("no"); } return 0; }
POJ 3450 Corporate Identity KMP+二分
二分串长,求出每个串长的所有子串,只要找到一个符合的子串即可。
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int MAXN = 4010; const int MAXL = 210; int N; char str[MAXN][MAXL]; char temp[MAXL]; char anser[MAXL]; int nextval[MAXL]; int len[MAXN]; void GetNextVal( char *s, int lenth ) { int i = 0, j = -1; nextval[0] = -1; while ( i < lenth ) { if ( j == -1 || s[i] == s[j] ) { ++i, ++j; if ( s[i] != s[j] ) nextval[i] = j; else nextval[i] = nextval[j]; } else j = nextval[j]; } return; } bool KMP( char *t, char *s, int lenth, int lenn ) { GetNextVal( t, lenth ); int i = 0, j = 0; while ( j < lenn ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lenth ) return true; } else i = nextval[i]; //if ( i == lenth ) return true; } return false; } bool check( int tpL ) { bool flag = false; bool ok = false; for ( int st = 0; st + tpL - 1 < len[0]; ++st ) { for ( int k = 0; k < tpL; ++k ) temp[k] = str[0][ st + k ]; temp[ tpL ] = '\0'; //puts(temp); ok = true; for ( int i = 1; i < N; ++i ) if ( !KMP( temp, str[i], tpL, len[i] ) ) { ok = false; break; } if ( ok ) { flag = true; if ( anser[0] == '\0' || ( strlen(anser) == strlen(temp) && strcmp( anser, temp ) > 0 ) || ( strlen(anser) < strlen(temp) ) ) strcpy( anser, temp ); } } return flag; } int main() { while ( scanf( "%d", &N ), N ) { int bound = 1 << 30; for ( int i = 0; i < N; ++i ) { scanf( "%s", str[i] ); len[i] = strlen( str[i] ); bound = min( bound, len[i] ); } int low = 0; int high = bound; int mid, ans = 0; anser[0] = '\0'; while ( low <= high ) { mid = ( low + high ) >> 1; if ( check( mid ) ) { ans = mid; low = mid + 1; } else high = mid - 1; } if ( !ans ) puts("IDENTITY LOST"); else puts(anser); } return 0; }
POJ 2752 Seek the Name, Seek the Fame
next函数的应用
#include <cstdio> #include <cstring> #include <cstdlib> const int MAXN = 400010; char str[MAXN]; int next[MAXN]; int ans[MAXN]; int len; void getNext( char *s ) { int i = 0, j = -1; next[0] = -1; while ( i < len ) { if ( j == -1 || s[i] == s[j] ) { ++i, ++j; next[i] = j; } else j = next[j]; } return; } int main() { while ( ~scanf( "%s", str ) ) { len = strlen(str); getNext( str ); int cnt = 0; ans[0] = len; int i = len; while ( next[i] > 0 ) { ans[ ++cnt ] = next[i]; i = next[i]; } for ( ; cnt >= 0; --cnt ) { printf( "%d", ans[cnt] ); if ( cnt ) putchar(' '); } puts(""); } return 0; }
HDU 2087 剪花布条
求一个串在另一个串中的出现次数,KMP模板题
#include <cstdio> #include <cstring> #include <cstdlib> const int MAXN = 1010; char str[MAXN]; char tmp[MAXN]; int nextval[MAXN]; int cnt; void getNextval(char *s, int *nextval, int length ) { int i=0,j=-1; nextval[0]=-1; while(i<length) { if(j==-1||s[i]==s[j]) { ++i; ++j; //next[i]=j; if (s[i]!=s[j]) nextval[i]=j; else nextval[i]=nextval[j]; } else j=nextval[j]; } } void KMP( char *t, char *s ) //s为主串,t为模式串 { int lenth = strlen(t); int len = strlen(s); getNextval( t, nextval, lenth ); int i = 0, j = 0; while ( j < len ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lenth ) { ++cnt; i = 0; } } else i = nextval[i]; } return; } int main() { while ( scanf( "%s", str ) == 1 && str[0] != '#' ) { scanf( "%s", tmp ); cnt = 0; KMP( tmp, str ); printf( "%d\n", cnt ); } return 0; }
HDU 2594 Simpsons’ Hidden Talents (next函数应用)
把两个串连接起来,中间用一个没出现过的字符分隔开,直接输出最后一个字符的next的值。
#include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 50010; char str[MAXN << 1]; char tmp[MAXN]; int nextval[MAXN << 1]; int length; void getNext(char s[],int next[]) { length=strlen(s); int i=0,j=-1; next[0]=-1; while(i<length) { if(j==-1||s[i]==s[j]) { ++i; ++j; next[i]=j; } else j=next[j]; } return; } int main() { while ( scanf( "%s%s", str, tmp ) == 2 ) { int len = strlen(str); str[len] = '$'; str[len + 1] = '\0'; strcat( str, tmp ); getNext( str, nextval ); str[ nextval[length] ] = '\0'; if ( nextval[length] > 0 ) printf( "%s %d\n", str, nextval[length] ); else puts("0"); } return 0; }
URAL 1423. String Tale ( KMP模板题 )
#include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 250010; int nextval[MAXN << 1]; char str[MAXN << 1]; char tmp1[MAXN]; char tmp2[MAXN]; int len; void getNextval( char s[],int nextval[], int length ) { int i=0,j=-1; nextval[0]=-1; while(i<length) { if(j==-1||s[i]==s[j]) { ++i; ++j; //next[i]=j; if (s[i]!=s[j]) nextval[i]=j; else nextval[i]=nextval[j]; } else j=nextval[j]; } } int KMP( char *t, char *s ) //s为主串,t为模式串 { int lenth = strlen(t); int len = strlen(s); getNextval( t, nextval, lenth ); int i = 0, j = 0; while ( j < len ) { if ( i == -1 || s[j] == t[i] ) { ++i, ++j; if ( i == lenth ) return j; } else i = nextval[i]; } return -1; } int main() { while ( scanf( "%d", &len ) == 1 ) { scanf( "%s%s", tmp1, tmp2 ); strcpy( str, tmp1 ); strcat( str, tmp1 ); int ans = KMP( tmp2, str ); //printf( "ans = %d\n", ans ); if ( ans == -1 ) puts("-1"); else if ( ans == len ) puts("0"); else printf( "%d\n", len + len - ans ); } return 0; }