字典树(Trie查找单词再也不用担心超时了)

字典树(Trie查找单词再也不用担心超时了)
  字典树与字典很相似,当你要查一个单词是不是在字典树中,首先看单词的第一个字母是不是在字典的第一层,如果不在,说明字典树里没有该单词,如果在就在该字母的孩子节点里找是不是有单词的第二个字母,没有说明没有该单词,有的话用同样的方法继续查找.字典树不仅可以用来储存字母,也可以储存数字等其它数据。

HDU 1247

Hat’s Words

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5977 Accepted Submission(s): 2232


Problem Description
A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.

Input
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
Only one case.

Output
Your output should contain all the hat’s words, one per line, in alphabetical order.

Sample Input
a
ahat
hat
hatword
hziee
word

Sample Output
ahat
hatword

#include<iostream>
#include<string.h>
const int N=50;
char str[50000][N],left[N],right[N];

struct Trie {
    Trie * next[26];
bool flag;//标记是否是单词的结尾
} *root;

void insert(char *str) {
    int len = strlen(str);
    Trie *s = root;
    for (int i = 0; i < len; i++)
        if (s->next[str[i] - 'a'])
            s = s->next[str[i] - 'a'];
        else {
            Trie* t = new Trie;
            memset(t, 0, sizeof (Trie));
            s->next[str[i] - 'a'] = t;
            s = t;
        }
s->flag = 1;
}

int find(char *str) {
    int len = strlen(str);
    Trie *s = root;
    for (int i = 0; i < len; i++)
        if (s->next[str[i] - 'a'])
            s = s->next[str[i] - 'a'];
        else
            return 0;
    return s->flag;
}


int main() {
    root = new Trie;
    memset(root, 0, sizeof (Trie));
int k = 0;
    while (gets(str[k]))
        insert(str[k++]);
    for (int i = 0; i < k; i++)
{
int len=strlen(str[i]);
for (int j = 1; j < len; j++)
{
strcpy(left,str[i]);
left[j]='\0';
strcpy(right,str[i]+j);
            if (find(left)&&find(right))
{
puts(str[i]);
break;
}
        }
}
  
    return 0;
}  



HDU 1251 

统计难题

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 14211    Accepted Submission(s): 6137


Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
 

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.
 

Output
对于每个提问,给出以该字符串为前缀的单词的数量.
 


Sample Input
banana
band
bee
absolute
acm
 
ba
b
band
abc
 
Sample Output
2
3
1
0

代码:
#include<iostream>
#include<cstring>
using namespace std;
struct tree
{
 tree *next[26];
 int ch;
 int flag;
} *root;

void insert(char *str) {
    int len = strlen(str);
    tree *s = root;
    for (int i = 0; i < len; i++)
        if (s->next[str[i] - 'a'])
  {
   s = s->next[str[i] - 'a'];
   s->ch++;
  }
        else {
            tree* t = new tree;
   
            memset(t, 0, sizeof (tree));
   t->ch=1;
            s->next[str[i] - 'a'] = t;
            s = t;
        }
    s->flag = 1;
}
 
int find(char *str)
{
 int n=strlen(str);
 tree *t=root;
 for(int i=0;i<n;i++)
 {
  if(t->next[str[i]-'a'])
   t=t->next[str[i]-'a'];
  else
   return 0;
 }
 int count=0;
 return t->ch;
  
}
void main()
{
 char a[15];
 root=new tree;
 memset(root,0,sizeof(tree));
 while(gets(a)&&a[0]!='\0')
 {
  insert(a);
 }
 
 while(gets(a))
 {
  printf("%d\n",find(a));
  
 }
}

  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值