字典树(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));

  

 }

}

  

    原文作者:Trie树
    原文地址: https://blog.csdn.net/wzningjie/article/details/11599771
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞