• cogs 647. [Youdao2010] 有道搜索框 Trie树 字典树


    647. [Youdao2010] 有道搜索框

    ★☆   输入文件:youdao.in   输出文件:youdao.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【问题描述】

    在有道搜索框中,当输入一个或者多个字符时,搜索框会出现一定数量的提示,如下图所示:

    现在给你 N 个单词和一些查询,请输出提示结果,为了简这个问题,只需要输出以查询词为前缀的并且按字典序排列的最前面的 8 个单词,如果符合要求的单词一个也没有请只输出当前查询词。

    【输入文件】

    第一行是一个正整数 N ,表示词表中有 N 个单词。 
    接下来有 N 行,每行都有一个单词,注意词表中的单词可能有重复,请忽略掉重复单词。所有的单词都由小写字母组成。 
    接下来的一行有一个正整数 Q ,表示接下来有 Q 个查询。 
    接下来 Q 行,每行有一个单词,表示一个查询词,所有的查询词也都是由小写字母组成,并且所有的单词以及查询的长度都不超过 20 ,且都不为空 
    其中: N<=10000,Q<=10000

    【输出文件】

    对于每个查询,输出一行,按顺序输出该查询词的提示结果,用空格隔开。

    【样例输入】 
    youdao.in

    10 

    ab 
    hello 
    that 
    those 
    dict 
    youdao 
    world 
    your 
    dictionary 

    bob 

    dict 
    dicti 
    yo 


    【样例输出】

    youdao.out

    bob 
    dict dictionary 
    dict dictionary 
    dictionary 
    youdao your 
    z

    呜呜 太惨了 就因为一个小小的错误就WA了半天 一定要注意这一道题 只输出字典序最小的前8个  不要超过8个!

    这一道题其实就是一个裸的Trie树 如果您还没学过(<<很抱歉 本博主还没有写一篇关于Trie树讲解的博客 还请谅解)

    然后再输入的时候把它们全部存起来

    每输入一个前缀

    就先搜索一下Trie树上能不能搜索到这个前缀

    如果不能搜索到  就直接按照题目要求 把这个前缀输出一遍直接完事儿

    要是搜到了 就把Trie树dfs一遍 就是在dfs的过程中 在变量中加一个数组 来存储答案字符串

    如果当前节点的f是true  就是是一个字符串的结尾 就输出到当前节点为止的字符拍起来形成的字符串

    但也要判断 如果已经搜索过8个字符串了 就直接返回return

    那么我们不禁心生疑问 那里有处理字典序最小?

    哈哈 这个还是非常简单的 因为在trie树的每一个节点不是都有一个for循环来枚举往下接着走那一条边嘛,因为for循环是从小到大的   所以自然针对每一个节点 就先走的更靠前的字典序更小的儿子son  组合起来就是字典序最小的字符串啦

    下面上代码 (可能有点长 但是很好理解 哈哈)

    #include<bits/stdc++.h>
    using namespace std;
    struct Trie{
        Trie* son[27];
        bool f;
        Trie()
        {
            for(int i=0;i<=26;i++)
                son[i]=NULL;
            f=false;
        }
    }Root;
    int num=0;
    void dfs(char s[],Trie* p,string ans)
    {
        if(num==8) return;
        if(p->f==true)
            printf("%s",s),cout<<ans<<" ",num++;
        ans+='0';
        for(int i=0;i<26;i++)
        {
            if(p->son[i]==NULL) 
                continue;
            ans[ans.length()-1]=i+'a';
            dfs(s,p->son[i],ans);
        }
    }
    int main()
    {
        freopen("youdao.in","r",stdin);
        freopen("youdao.out","w",stdout);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            char s[25];
            scanf("%s",s);
            int len=strlen(s);
            Trie* p=&Root;
            for(int j=0;j<len;j++)
            {
                int x=s[j]-'a';
                if(p->son[x]==NULL)
                    p->son[x]=new Trie;
                p=p->son[x];
            }
            p->f=true;
        }
        int q;
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            char s[25];
            scanf("%s",s);
            int len=strlen(s);
            bool Find=true;
            Trie* p=&Root;
            string ans="";
            for(int j=0;j<len;j++)
            {
                int x=s[j]-'a';
                if(p->son[x]==NULL)
                {
                    Find=false;
                    break;
                }
                p=p->son[x];
            }
            if(!Find)
                puts(s);
            else
                dfs(s,p,ans),printf("
    ");
            num=0;
        }
        return 0;
     } 
  • 相关阅读:
    物联网操作系统HelloX开发者入门指南
    【 D3.js 高级系列 】 总结
    【 D3.js 高级系列 — 10.0 】 思维导图
    android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
    OpenGL 顶点缓存对象
    OpenGL顶点数组
    【 D3.js 高级系列 — 9.0 】 交互式提示框
    如何在 Linux 上录制你的终端操作
    程序员诗词大赛开始了_你看过吗?
    程序员与代码的搞笑日常
  • 原文地址:https://www.cnblogs.com/Tidoblogs/p/11360745.html
Copyright © 2020-2023  润新知