hdu 1247 Hat’s Words(字典树)

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

分析:这道题可以使用stl中的map直接来解决,也可以使用字典树来解决,当然字典树的效率会更高

(1)stl解法不做过多的解释,这里有网上一个stl解法的链接  http://hi.baidu.com/mingyiyiyi_3/item/25835459866641494eff20f5

(2)字典树解法,字典树 (详细看链接解释)

定义一个字典树结构体

typedef struct Trie
{
    bool flag;//从根到此是否为一个单词
    Trie *next[MAXNUM];
}Trie;

字典树的插入操作
void insert(char *word)
{
    Trie *tem = root;
    while(*word!='\0')
    {
        if(tem->next[*word-'a']==NULL)
        {
            Trie *cur = (Trie *)malloc(sizeof(Trie));
            for(int i=0;i<MAXNUM;i++)
            cur->next[i]=NULL;
            cur->flag=false;
            tem->next[*word-'a']=cur;
        }
        tem = tem->next[*word-'a'];
        word++;
    }
    tem->flag=true;
}

以上两段代码是字典树的核心,要先弄懂。然后针对本题,flag是标志从根到当前位置是否可以组成一个单词,是为true,否为false。然后搜索每个单词是否有两个单词组成,这时就要把每个单词拆分,一个长度为n的单词可以拆分为n-1组组合,然后枚举判断是否在该字典树集合内。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXNUM 26
using namespace std;

//单词
char words[50005][100];
//定义字典树
typedef struct Trie
{
    bool flag;//从根到此是否为一个单词
    Trie *next[MAXNUM];
}Trie;

Trie *root;

void init()
{
    root = (Trie *)malloc(sizeof(Trie));
    root->flag=false;
    for(int i=0;i<MAXNUM;i++)
    root->next[i]=NULL;
}

void insert(char *word)
{
    Trie *tem = root;
    while(*word!='\0')
    {
        if(tem->next[*word-'a']==NULL)
        {
            Trie *cur = (Trie *)malloc(sizeof(Trie));
            for(int i=0;i<MAXNUM;i++)
            cur->next[i]=NULL;
            cur->flag=false;
            tem->next[*word-'a']=cur;
        }
        tem = tem->next[*word-'a'];
        word++;
    }
    tem->flag=true;
}

bool search(char *word)
{
    Trie *tem = root;
    for(int i=0;word[i]!='\0';i++)
    {
        if(tem==NULL||tem->next[word[i]-'a']==NULL)
        return false;
        tem=tem->next[word[i]-'a'];
    }
    return tem->flag;
}


int main()
{
    init();
    int t=0;
    char w[100];
    while(scanf("%s",words[t])!=EOF)
    {

        insert(words[t]);
        t++;
    }
    for(int i=0;i<t;i++)
    {
        memset(w,'\0',sizeof(w));
        for(int j=0;words[i][j]!='\0';j++)
        {
            *(w+j)=*(words[i]+j);
            if(search(w)&&search((words[i]+j+1)))
            {
                printf("%s\n",words[i]);
                break;
            }
        }

    }
    return 0;
}

posted on 2012-11-02 09:01  NewPanderKing  阅读(527)  评论(0编辑  收藏  举报

导航