码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1247-Hat’s Words-(字典树)

时间:2019-11-17 17:46:48      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:math   iostream   max   while   http   hat   查询   for   clu   

http://acm.hdu.edu.cn/showproblem.php?pid=1247

题意:给出一堆单词,求哪些单词是其中某两个单词拼接起来的。

题解:用字典树存储所有的单词,标记结束点,再次遍历单词的时候如果遍历过程遇到结束点则表明有单词是该单词的前缀,查找后半段字母(后缀)看看最后能不能遇到结束点,如果遇到了则该单词是某两个单词的前后缀,可以输出。详看注释。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define inf 0x3f3f3f3f
const double pi=3.1415926;
using namespace std;
int maxx=50005;
typedef struct node
{
    int flag;///判断是否单词在这里就完了,作为前缀
    node *next[27];
};
node* root=new node();///根节点始终为空

void insert(char* s)
{
    node* p=root;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int x=s[i]-a;
        if((p->next[x])==NULL)///当前遍历到的字母还没有开创节点
        {
            p->next[x]=new node();///新开一个节点
            p=p->next[x];
        }
        else
        {
            p=p->next[x];
        }
    }
    p->flag=1;///标记有单词在这里结束
}

int find2(char*s ,int now)///查后缀
{
    node* p=root;
    int len=strlen(s);
    int i;
    for(i=now;i<len;i++)///从now下标开始查询后缀,一直找
    {
        int x=s[i]-a;
        p=p->next[x];
        if(p!=NULL)
        {
            if(i==(len-1) && p->flag==1)///s[now]-s[len-1]即后缀,是完整的单词
                return 1;
        }
        else
            return 0;
    }
    return 0;
}

int find(char* s)///查前缀,查到转后缀
{
    node* p=root;
    int len=strlen(s);
    int i;
    for(i=0;i<len;i++)
    {
        int x=s[i]-a;
        p=p->next[x];///进入当前字母的节点
        if(p!=NULL)
        {
            if(p->flag==1 && i!=(len-1) && find2(s,i+1))///有单词到这里断了,即有前缀,不能是这个单词本身,所以后续还要有字母
                return 1;      ///如果find2成功才可以return 1,否则继续,可能还有别的前缀和后缀单词
        }
        else
            return 0;
    }
    return 0;
}


int main()///hdu1247 字典树
{
    int i=0;
    char a[maxx][30];
    while(scanf("%s",a[i])!=EOF)
    {
        insert(a[i]);
        i++;
    }
    for(int j=0;j<i;j++)
    {
        if(find(a[j]))
            printf("%s\n",a[j]);
    }
    return 0;
}

没有看到纯数组模拟字典树的题解代码,不得不手动写指针,困扰了挺长时间。看到有用map和string解决的,感觉那不是正道,还是把字典树学了。

hdu1247-Hat’s Words-(字典树)

标签:math   iostream   max   while   http   hat   查询   for   clu   

原文地址:https://www.cnblogs.com/shoulinniao/p/11876906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!