http://acm.hdu.edu.cn/showproblem.php?pid=1251
hdu1251
题意:先几个单词空一行再给几个前缀,判断每个前缀在单词中出现的次数
做法:设置count在字典树中,对于字符串,走到每个字符时都把count ++。查找到时候,如果未走到头就是1,走到头了就是count
链表版本
//字典树,根节点不算 //字典树第一发,g++超内存。c++不超 #include<cstdio> #include<cstring> #include <iostream> using namespace std; struct node { node *nexta[26]; int countx; node() { memset(nexta,NULL,sizeof(nexta)); //memset(nexta,NULL,sizeof(nexta)); countx = 0; } }; node *p,*root = new node(); void build(char a[]) { p = root; int t,l = strlen(a); for(int i = 0;i < l; i++) { t = a[i] - 'a'; if(p->nexta[t] == NULL) { p->nexta[t] = new node(); } p = p -> nexta[t]; p->countx ++; } } int findx(char a[]) { p = root; int t,l = strlen(a); for(int i = 0; i < l; i ++) { t = a[i] - 'a'; if(p->nexta[t] == NULL) { return 0; } p = p ->nexta[t]; } return p -> countx; } int main() { //freopen("in.txt","r",stdin); char s[11]; while(gets(s) && strlen(s)) { build(s); } while(gets(s) && strlen(s)) { printf("%d\n",findx(s)); } return 0; }数组版本
//字典树,根节点不算 //字典树,数组版本。注意根节点要在建树之前清零 #include<cstdio> #include<cstring> #include <iostream> using namespace std; struct node { int nexta[26]; int countx; }f[1000000]; void init(int a)//新增函数 { memset(f[a].nexta,-1,sizeof(f[a].nexta)); f[a].countx = 0; } int cnt = 1; void build(char a[]) { int p = 0; int t,l = strlen(a); for(int i = 0;i < l; i++) { t = a[i] - 'a'; if(f[p].nexta[t] == -1) { f[p].nexta[t] = cnt; init(cnt); cnt++; } p = f[p].nexta[t]; f[p].countx ++; } } int findx(char a[]) { int k = 0; int t,l = strlen(a); for(int i = 0; i < l; i ++) { t = a[i] - 'a'; k = f[k].nexta[t]; if(k == -1) return 0; } return f[k].countx; } int main() { //freopen("in.txt","r",stdin); char s[11]; init(0);//注意根节点要先清零 while(gets(s) && strlen(s)) { build(s); } while(gets(s) && strlen(s)) { printf("%d\n",findx(s)); } return 0; }