zoukankan      html  css  js  c++  java
  • Trie树(字典树)-题解 P2580 【于是他错误的点名开始了】

    此题可以用STL中的map做,但是了解一下Trie树这个数据结构也是必须的。

    Trie树(又称字典树)有以下特点:

    1. 根节点不包含字符,除它之外的每一个节点都包含一个字符。

    2. 从根节点到某一节点,路径上经过所有字符连起来为该节点对应字符串

    3. 每个节点的子节点包含字符不同,也就意味着字符是可以公用的

    于是我们用这样一个结构体表示每一个节点:

    在本题中可以用动态数组vector贮存每个子节点

             struct node{
                char c;//该点对应字符
                vector<struct node*>s;//储存儿子
                int tag;//标记是否为某一字符串结尾
                int rep; //应题目要求判断是否重复
               }*root=new struct node;
    

    当然字典树有两个函数必不可少,分别是add(插入)和query(查询)。
    具体怎么实现还看代码:

        #include <cstdio>
        #include <iostream>
        #include <cstdlib>
        #include <vector>
        #include <string>
        using namespace std;
        struct node{
            char c;
            vector<struct node*>s;
            int tag;
            int rep; 
        }*root=new struct node;
        void add(string str)
        {
            struct node*p=root;
            for(int i=0;i<str.length();i++)
            {
                int j;
                for(j=0;j<p->s.size();j++)
                  if(p->s[j]->c==str[i])break;//如果找到对应公用字符
                if(j==p->s.size())//如果遍历完后没找到新建一个
                {
                    struct node *newnode =new struct node;
                    newnode->c=str[i];
                    newnode->s.clear();
                    newnode->tag=0;
                    newnode->rep=0; 
                    p->s.push_back(newnode);
                    p=newnode;
                }
                else p=p->s[j];
            } 
            p->tag=1;//标志此节点为一字符串结尾
        }
        int query(string str)
        {
            struct node*p=root;
            for(int i=0;i<str.length();i++)
            {
                int j;
                for(j=0;j<p->s.size();j++)  
                    if(p->s[j]->c==str[i]) 
                         {break;}
                if(j==p->s.size()) //如果遍历完后没找到
                   return 0;
                p=p->s[j];
            }
            if(p->rep!=3)
            {
                p->rep=3;return p->tag;//找到的字符可能只是某一前缀而非整个字符串,所以需要一个tag标记
            }
            else if(p->rep==3)return p->rep;
        }
        int main()
        {
            int n,m;
            char tag[50];
            cin>>n;
            root->s.clear();
            for(int i=1;i<=n;i++)
            {
                string str;
                cin>>str;
                add(str);
            }
            cin>>m;
            for(int i=1;i<=m;i++)
            {
                string str;
                cin>>str;
                int flag=query(str);
                if(flag==0)puts("WRONG");
                else if(flag==1)puts("OK");
                else if(flag==3)puts("REPEAT");
            }
            return 0;
    }
    
  • 相关阅读:
    R 包安装问题
    特征值分解与奇异值分解
    向量内积&外积
    hdu_3449(有依赖背包)
    Gene co-expression analysis for functional classification and gene–disease predictions
    MCMC & 贝叶斯
    继承(来自视频)
    面向对象 创建对象
    mongodb笔记(三)
    mongodb笔记(二)
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8478889.html
Copyright © 2011-2022 走看看