HDU 2594 EX_KMP或者字符串hash
来源:互联网 发布:java简历工作内容 编辑:程序博客网 时间:2024/06/05 02:47
题意:给你2个字符串a , b 。问 a的前缀和b的后缀的公共部分最长是多少。
思路:把a从前往后hash,把b从后往前hash,如果hash值相等,那么代表两个字符串相等,那么更新长度。
最后输出这个长度的最大值即可。
还可以用EX_KMP搞,我们可以把两个字符串连成一个,然后根据EX_KMP的NEXT数组的作用,直接就可以判断后缀是否等于前缀。
先来一发HASH的代码。
#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define Max 2505#define FI first#define SE second#define ll long long#define PI acos(-1.0)#define inf 0x7fffffff#define LL(x) ( x << 1 )#define bug puts("here")#define PII pair<int,int>#define RR(x) ( x << 1 | 1 )#define mp(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )using namespace std;#define uint unsigned int#define N 55555char a[N] , b[N] ;int main() { while(scanf("%s%s",a,b) != EOF){ int la = strlen(a) ;int lb = strlen(b) ; uint seed = 31 , hasha = 0 , hashb = 0 , Hx = 1 ; int posa = 0 , posb = lb - 1 ; int ans = -1 ; while(posa < la && posb >= 0){ hasha = hasha * seed + a[posa] ; hashb = hashb + Hx * b[posb] ; hasha &= inf ; hashb &= inf ; if(hasha == hashb)ans = posa + 1 ; Hx *= seed ; posa ++ ; posb -- ; } for (int i = 0 ; i < ans ; i ++ )cout << a[i] ; if(ans == -1)cout << 0 << endl; else cout<< " " << ans << endl; } return 0;}再来一发EX_KMP的代码。
#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define Max 2505#define FI first#define SE second#define ll long long#define PI acos(-1.0)#define inf 0x3fffffff#define LL(x) ( x << 1 )#define bug puts("here")#define PII pair<int,int>#define RR(x) ( x << 1 | 1 )#define mp(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )using namespace std;#define N 111111int Next[N] ;char b[N] ;void EX_Next(){ int x = 0 ; int l = strlen(b) ; Next[0] = l ; while(x < l - 1 && b[x] == b[x + 1])x ++ ; Next[1] = x ; x = 1 ; for (int k = 2 ; k < l ; k ++ ){ int p = x + Next[x] - 1 , L = Next[k - x] ; if(k - 1 + L >= p){ int j = (p - k + 1) > 0 ? (p - k + 1) : 0 ; while(k + j < l && b[k + j] == b[j]) j ++ ; Next[k] = j ; x = k ; }else { Next[k] = L ; } }}int main() { while(scanf("%s",b) != EOF){ int l = strlen(b) ; scanf("%s",b + l) ; EX_Next() ; int l1 = strlen(b) ;int ans = -1 ; for (int i = l ; i < l1 ; i ++ ){ int now = Next[i] ; if(i + now == l1) ans = max(ans , now ) ; } ans = ans >= l ? l : ans ; for (int i = 0 ; i < ans ; i ++ )cout << b[i] ; if(ans == -1)cout << 0 << endl ; else cout << " " << ans << endl; } return 0;}
HDU 1867 同样的意思,给定两个字符串,找出一个串的前缀和一个串的后缀的最大重复字串,然后将两个串合起来,当然重叠部分算一次,然后输出最后的串。
注意的是这道题两个字符串哪个在前那个在后不知道,所有做两次EX_KMP,分别求出各串最为前缀和后缀能匹配的最大长度,最后输出长度小字典序小的那个即可。
#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define Max 2505#define FI first#define SE second#define ll long long#define PI acos(-1.0)#define inf 0x3fffffff#define LL(x) ( x << 1 )#define bug puts("here")#define PII pair<int,int>#define RR(x) ( x << 1 | 1 )#define mp(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )using namespace std;#define N 211111int Next[N] ;void EX_NEXT(char *a) { int l = strlen(a) ; int x = 0 ; Next[0] = l ; while(x < l - 1 && a[x] == a[x + 1]) x ++ ; Next[1] = x ; x = 1 ; for (int k = 2 ; k < l ; k ++ ) { int p = x + Next[x] - 1 , L = Next[k - x] ; if(k - 1 + L >= p) { int j = (p - k + 1) > 0 ? (p - k + 1 ) : 0 ; while(k + j < l && a[k + j] == a[j]) j ++ ; Next[k] = j ; x = k ; } else Next[k] = L ; }}string gao(char *x , char *y){ int l1 = strlen(x) , l = l1 , posy = 0 ; while(y[posy])x[l ++ ] = y[posy ++ ] ; x[l] = '\0' ;EX_NEXT(x) ;int l2 = strlen(x) ;int num = 0 ; for (int i = l1 ; i < l2 ; i ++ ) if(i + Next[i] == l2)num = max(num , Next[i]) ; string ff = y ; while(x[num] && num < l1)ff += x[num ++] ; return ff ;}char a[N] , b[N] ;char x[N] , y[N] ;string check(string ans , string tans){ if(ans.size() > tans.size())return tans ; if(ans.size() < tans.size())return ans ; return ans > tans ? tans : ans ;}int main() { while(scanf("%s%s",b,a) != EOF) { strcpy(x , a) ;strcpy(y , b) ; printf("%s\n",check(gao(a , b) , gao(y , x)).c_str()) ; } return 0 ;}
- HDU 2594 EX_KMP或者字符串hash
- hdu 2594 hash字符串
- HDU 4333 Revolving Digits(EX_KMP)
- 字符串算法(KMP+MANACHER+EX_KMP)总结
- HDU 4821 字符串hash
- hdu 4821(字符串hash)
- fzu 2137 字符串hash或者后缀数组
- hdu 4993(简单枚举或者hash)
- [hdu 4821]String 字符串hash
- HDU 4821 String 字符串hash
- [字符串hash] hdu 4821 String
- HDU 4821 String 字符串HASH
- HDU 4821 String 字符串HASH
- hdu 4821 String 字符串hash
- hdu 4886 字符串 hash+暴力
- poj 3461 字符串单串匹配--KMP或者字符串HASH
- codeforces #336 E. Marbles (字符串hash或者kmp匹配)
- HDU 1880 字符串hash 入门题
- Excel VBA入门(4) - Workbook常用功能及方法介绍
- mmap对get_free_pages 等的不同做法
- 基于COM技术的ATM自动存款机实现(C#版)
- ARM7中断向量重映射的问题
- 7 个效果震憾的 HTML5 应用组件
- HDU 2594 EX_KMP或者字符串hash
- Linux操作系统的选择
- 国外CMS演示示例
- Canvas 属性,方法
- LeetCode (F)
- 新人报到
- Problem J: Scholarship
- ecshop实现立刻购买与添加到购物车并存的方法
- IO_01