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


    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
    ",a[j]);
        }
        return 0;
    }

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

  • 相关阅读:
    吴裕雄--天生自然python学习笔记:python 用 Tesseract 识别验证码
    吴裕雄--天生自然python学习笔记:python安装配置tesseract-ocr-setup-3.05.00dev.exe
    吴裕雄--天生自然python学习笔记:python 用 Open CV通过人脸识别进行登录
    吴裕雄--天生自然python学习笔记:python 用 Open CV抓取摄像头视频图像
    HDU4278 Faulty Odometerd
    最大流 总结
    HDU1411 欧拉四面体
    HDU3336 Count the string
    HDU1711
    HDU2203 亲和串
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11876906.html
Copyright © 2020-2023  润新知