HDU 1251 统计难题(字典树Trie)
http://acm.hdu.edu.cn/showproblem.php?pid=1251
题意:
给你多个单词,然后在给你一个字符串s,现在要问你以该字符串s为前缀的单词数目有多少个?
分析:
标准的字典树应用,我们只需要用树节点的v值表示以树根root到当前节点的路为前缀的单词数即可.
在插入新单词节点的时候,该单词节点路过的所有Trie节点v都要+1.
查询的时候,如果能查到该前缀,直接输出v值,否则输出0.
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; /****************************字典树Trie模板***********************************/ #define MAX 26 struct Trie { Trie *next[MAX]; int v; void init() { for(int i=0;i<MAX;i++) next[i]=NULL; v=1; } }; Trie root; void Trie_insert(Trie *root,char *s) { int n=strlen(s); Trie *p=root,*q; p->v++; for(int i=0;i<n;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) { q=(Trie*)malloc(sizeof(Trie)); q->init(); p->next[id]=q; p=q; } else { p->next[id]->v++; p=p->next[id]; } } } int Trie_search(Trie *root,char *s) { int n=strlen(s); Trie *p=root; for(int i=0;i<n;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) return 0;//没找到该前缀 else p=p->next[id]; } return p->v; } void Trie_delete(Trie *root) { if(root==NULL) return ; else { for(int i=0;i<MAX;i++) Trie_delete(root->next[i]); } free(root); } /****************************字典树Trie模板***********************************/ int main() { root.init(); char s[100]; while(gets(s)) { if(strcmp(s,"")==0) break; Trie_insert(&root,s); } while(gets(s)) { printf("%d\n",Trie_search(&root,s)); } Trie_delete(&root); return 0; }