HDU 2846--字典树
http://acm.hdu.edu.cn/showproblem.php?pid=2846
题意是给出一些模式串,再给出几个询问,询问给出的字符串在多少个模式串中出现
比如字符串abc所含的字串有a,ab,abc,b,bc,c
可用字典树解决,字典树能很好的处理前缀出现的次数,所以可将模式串分解,依次插入
需要注意的是对于同一个模式串的不同子串可能有相同的前缀,为了避免多次计算,可以添加字典树节点的信息,添加num记录最后插入的字符串是第num个模式串的子串。
关键在于怎么控制避免多次计算。。。
在写的时候脑残的先计数然后在进行移位,应该要反过来。。。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 struct node{ 6 int num; 7 int count; 8 node *next[26]; 9 node() 10 { 11 num=0; 12 count=0; 13 memset(next,0,sizeof(next)); 14 } 15 }; 16 node *root=new node; 17 void build(char *a,int j) 18 { 19 node *p=root; 20 for(int i=0;a[i];i++) 21 { 22 int k=a[i]-'a'; 23 if(p->next[k]==NULL) 24 { 25 p->next[k]=new node; 26 p=p->next[k]; //先移位,再计数 27 p->num=j; 28 p->count++; 29 } 30 else 31 { 32 p=p->next[k];//先移位,再计数 33 if(p->num!=j) 34 { 35 p->num=j; 36 p->count++; 37 } 38 } 39 } 40 } 41 int Find(char *b) 42 { 43 node *p=root; 44 for(int i=0;b[i];i++) 45 { 46 int k=b[i]-'a'; 47 if(p->next[k]==NULL) 48 return 0; 49 p=p->next[k]; 50 } 51 return p->count; 52 } 53 int main() 54 { 55 int n,m; 56 char a[30],b[30]; 57 while(~scanf("%d",&n)) 58 { 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%s",a); 62 for(int j=0;a[j];j++) 63 build(&a[j],i); 64 } 65 scanf("%d",&m); 66 while(m--) 67 { 68 scanf("%s",b); 69 printf("%d\n",Find(b)); 70 } 71 } 72 return 0; 73 }
posted on 2013-02-05 16:10 acoderworld 阅读(69) 评论(0) 收藏 举报
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 我在厂里搞 wine 的日子
· 如何通过向量化技术比较两段文本是否相似?
· 35+程序员的转型之路:经济寒冬中的希望与策略
· JavaScript中如何遍历对象?
· 领域模型应用
· 独立项目运营一周年经验分享
· 一款开源免费、通用的 WPF 主题控件包
· 独立开发,这条路可行吗?
· 【定时任务核心】究竟是谁在负责盯着时间,并在恰当时机触发任务?
· 解决了AI聊天的10个痛点后,我又做了一个新功能:交叉分析表