UVA 10391 - Compound Words 字符串hash
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1332
题目大意:
给定一个词典(已经按照字典序排好),要求找出其中所有的复合词,即恰好由两个单词连接而成的单词。(按字典序输出)
思路:
对于每个单词,存入Hash表,然后对每个单词拆分。
Hash函数的选取可以看:https://www.byvoid.com/blog/string-hash-compare/
我的这个是BKDRHash。
乘以一个比他大的素数。
关于:0x7fffffff(即int_max,最大的整型范围。why? 16进制每位由4个二进制表示,7二进制位0111,其他的f为1111.)
#include<cstdio> #include<cstring> const int MAXN=120000+10; int head[MAXN],len,n; char data[MAXN][30]; typedef unsigned long long LL; struct edge { int index,next; }e[MAXN]; int gethash(char *s) { LL seed=131; LL res=0; int L=strlen(s); for(int i=0;i<L;i++) { res=res*seed+s[i]; } return (res& 0x7fffffff )% MAXN; } void add(char *s,int index) { int id=gethash(s); e[len].index=index; e[len].next=head[id]; head[id]=len++; } bool find(char *s) { int id=gethash(s); for(int i=head[id];i!=-1;i=e[i].next) { int index=e[i].index; if(strcmp(s,data[i])==0) return true; } return false; } int main() { n=len=0; memset(head,-1,sizeof(head)); while(~scanf("%s",data[n])) { add(data[n],n); n++; } for(int i=0;i<n;i++) { int L=strlen(data[i]); L--; for(int j=1;j<L;j++) { char temp[30]; strcpy(temp,data[i]+j); char flag=data[i][j]; data[i][j]='\0'; if(find(data[i]) && find(temp)) { data[i][j]=flag; puts(data[i]); break; } data[i][j]=flag; } } return 0; }
新 blog : www.hrwhisper.me