hdu 1247(Trie)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247

思路:用字典树插入所有单词后直接枚举每个单词的每个分割点每个分割点的位置都入栈),然后再依此出栈判断此分割点分成的两个字符串是否都存在即可,如果所有的情况都不存在,返回false,否则,返回true;

View Code
 1 #include<iostream>
 2 using namespace std;
 3 
 4 struct Tire{
 5     bool Is;
 6     Tire *next[26];
 7 };
 8 Tire *root;
 9 
10 void CreateTire(char str[]){
11     int len=strlen(str);
12     Tire *p=root,*q;
13     for(int i=0;i<len;i++){
14         int id=str[i]-'a';
15         if(p->next[id]==NULL){
16             q=(Tire *)malloc(sizeof(Tire));
17             q->Is=false;
18             for(int i=0;i<26;i++){
19                 q->next[i]=NULL;
20             }
21             p->next[id]=q;
22             p=p->next[id];
23         }else {
24             p=p->next[id];
25         }
26     }
27     p->Is=true;//单词结尾标记为true;
28 }
29 
30 bool Search(char str[]){
31     int i=0,top=0,stack[1010];
32     int len=strlen(str);
33     Tire *p=root;
34     while(str[i]){
35         int k=str[i++]-'a';
36         if(p->next[k]==NULL)return false;
37         p=p->next[k];
38         if(p->Is&&str[i]){
39             stack[top++]=i;//找到该单词还有子单词的分割点,入栈
40         }
41     }
42     //从可能的分割点去找
43     while(top){
44         bool tag=true;
45         i=stack[--top];
46         p=root;
47         while(str[i]){
48             int k=str[i++]-'a';
49             if(p->next[k]==NULL){
50                 tag=false;
51                 break;
52             }
53             p=p->next[k];
54         }
55         //找到最后并且存在
56         if(tag&&p->Is){
57             return true;
58         }
59     }
60     return false;
61 }
62 
63 int main(){
64     char str[50010][17];
65     root=(Tire *)malloc(sizeof(Tire));
66     for(int i=0;i<26;i++){
67         root->next[i]=NULL;
68     }
69     root->Is=false;
70     int k=0;
71     while(~scanf("%s",str[k])){
72         CreateTire(str[k++]);
73     }
74     for(int i=0;i<k;i++){
75         if(Search(str[i])){
76             printf("%s\n",str[i]);
77         }
78     }
79     return 0;
80 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值