zoukankan      html  css  js  c++  java
  • Trie的C++实现及HDU1251,hdu1671

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    template<int Size>
    struct trie_node{
    
      bool terminable; //表示节点为字符串的结尾
      int node;       //子节点的个数
      trie_node *child[Size]; //儿子节点
      trie_node():terminable(false), node(0){
          memset(child,0,sizeof(child)); //初始化节点
      }
    
    };
    template<int Size,typename Index>
    class trie{
        public:
            //定义类名
            typedef trie_node<Size> node_type;
            typedef trie_node<Size> *link_type;
    
            //构造函数
            trie(Index i=Index()):index(i){ }
    
            //清空函数,用于析构
            void clear(){
              clear_node(root);
              for(int i=0;i<Size;i++)
                  root.child[i]=0;
            }
            //插入
            template<typename Iterator>
            void insert(Iterator begin,Iterator end){
               link_type cur= &root;//当前插入结点为根
               while(begin!=end){
                  if(!cur->child[index[*begin]]){//没有插入过
                    cur->child[index[*begin]]=new node_type;
                    cur->node++; //插入后,父亲多了一个儿子
                  }
                  cur=cur->child[index[*begin]]; //向下走
                   begin++; //迭代器往前走!
               }
               cur->terminable=true;
            
            }
    
            //重载c风格插入
            void insert(const char * str){
               insert(str,str+strlen(str));
            }
    
            //查找
            template <typename Iterator>
            bool find(Iterator begin,Iterator end){
                 link_type cur=&root;
                 while(begin!=end){
                 
                     if(!cur->child[index[*begin]]) //没有节点啊!!!
                         return false;
                     cur=cur->child[index[*begin]];
    
                    begin++;
                 
                 }        
                 return cur->terminable; //是否为字符串
            }
    
            //重载c风格
            bool find(const char *str){
            
               return find(str,str+strlen(str));
            }
    
            //删除字符串
           template<typename Iterator>
           bool earse (Iterator begin,Iterator end){
              bool result;
              earse_node(begin,end,root,result);
              return result;    
               
              
           }
    
           //c语言风格
           bool erase(char *str){
             return earse(str,str+strlen(str));
           
           }
    
           template<typename Functor>
               void traverse(Functor &execute =Functor()){
                 visit_node(root,execute);
               
               }
        private:
           //访问结点
           template<typename Functor>
            void visit_node(node_type cur,Functor &execute){
                execute(cur);
                for(int i=0;i<Size;i++){//dfs
                  if(cur.child[i]==0) continue;
                  visit_node(*cur.child[i],execute);
                
                }
            }
    
           //清空
           void clear_node(node_type cur){
              for(int i=0;i<Size;i++){
                 if(cur.child[i]==0)continue; //不存在
                 clear_node(*cur.child[i]);
                 delete cur.childe[i];
                 cur.child[i]=0;
                 if(--cur.node==0) break; //没有节点了
              
              }
          
           }
    
           //一边搜索一边删除
           template<typename Iterator>
           bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
                if(begin==end){
                     result=cur.terminable;
                     cur.terminalbe=false;
                     return cur.node==0;
                
                }                 
               //当孩子不存在,结果假,返回假
                if(cur.child[index[*begin ]]==0) return !(result=false);
                else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
                   delete cur.child[index[*begin]];
                   cur.child[index[*begin]]=0;
                   if(--cur.node==0&&cur.terminable==false ) return true;
                
                }
                return false;
                         
           
           }
           //根
           node_type root;
           //字符转索引,类似hash
           Index index;
    
    };
    
    class IndexClass{
        public:
            int operator[](const char key){
                return key%26; //一个映射
            
            }
    
    };
    
    
    int main(){
        trie<26,IndexClass> t;
        t.insert("tree");
        t.insert("tea");
        t.insert("act");
        t.insert("adv");
        t.insert("ate");
        if(t.find("tree")){
          cout<<"find!";
        }
        char  str[50];
        while(scanf("%s",str)!=EOF){
            if(t.find(str)==1){
              cout<<"find"<<endl;
            }
          
        }
        return 0;
    
    
    }

    大部分参考http://blog.csdn.net/luxiaoxun/article/details/7937589

    后来用1251裸题测试了一下。

    Ac果断高兴啊!

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    template<int Size>
    struct trie_node{
    
      bool terminable; //表示节点为字符串的结尾
      int node;       //子节点的个数
      trie_node *child[Size]; //儿子节点
      trie_node():terminable(false), node(0){
          memset(child,0,sizeof(child)); //初始化节点
      }
    
    };
    template<int Size,typename Index>
    class trie{
        public:
            //定义类名
            typedef trie_node<Size> node_type;
            typedef trie_node<Size> *link_type;
    
            //构造函数
            trie(Index i=Index()):index(i){ }
    
            //清空函数,用于析构
            void clear(){
              clear_node(root);
              for(int i=0;i<Size;i++)
                  root.child[i]=0;
            }
            //插入
            template<typename Iterator>
            void insert(Iterator begin,Iterator end){
               link_type cur= &root;//当前插入结点为根
               while(begin!=end){
                  if(cur->child[index[*begin]]){//插入过
                     cur=cur->child[index[*begin]];
                     ++(cur->node);
    
                  }else{
                      cur->child[index[*begin]]=new node_type;
                    ++(cur->child[index[*begin]]->node);
                    cur=cur->child[index[*begin]];
    
                  }
    
    
    
    
                   begin++; //迭代器往前走!
               }
               cur->terminable=true;
    
            }
    
            //重载c风格插入
            void insert(const char * str){
               insert(str,str+strlen(str));
            }
    
            //查找
            template <typename Iterator>
            bool find(Iterator begin,Iterator end){
                 link_type cur=&root;
                 while(begin!=end){
    
                     if(!cur->child[index[*begin]]) //没有节点啊!!!
                         return false;
                     cur=cur->child[index[*begin]];
    
                    begin++;
    
                 }
                 return cur->terminable; //是否为字符串
            }
            template <typename Iterator>
            int findNum(Iterator begin,Iterator end){
                 link_type cur=&root;
                 while(begin!=end){
    
                     if(!cur->child[index[*begin]]) //没有节点啊!!!
                         return 0;
                     cur=cur->child[index[*begin]];
    
                    begin++;
    
                 }
    
                 return cur->node; //是否为字符串
            }
            //重载c风格
            int findNum(const char *str){
    
               return findNum(str,str+strlen(str));
            }
    
            //重载c风格
            bool find(const char *str){
    
               return find(str,str+strlen(str));
            }
    
            //删除字符串
           template<typename Iterator>
           bool earse (Iterator begin,Iterator end){
              bool result;
              earse_node(begin,end,root,result);
              return result;
    
    
           }
    
           //c语言风格
           bool erase(char *str){
             return earse(str,str+strlen(str));
    
           }
    
           template<typename Functor>
               void traverse(Functor &execute =Functor()){
                 visit_node(root,execute);
    
               }
        private:
           //访问结点
           template<typename Functor>
            void visit_node(node_type cur,Functor &execute){
                execute(cur);
                for(int i=0;i<Size;i++){//dfs
                  if(cur.child[i]==0) continue;
                  visit_node(*cur.child[i],execute);
    
                }
            }
    
           //清空
           void clear_node(node_type cur){
              for(int i=0;i<Size;i++){
                 if(cur.child[i]==0)continue; //不存在
                 clear_node(*cur.child[i]);
                 delete cur.childe[i];
                 cur.child[i]=0;
                 if(--cur.node==0) break; //没有节点了
    
              }
    
           }
    
           //一边搜索一边删除
           template<typename Iterator>
           bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result){
                if(begin==end){
                     result=cur.terminable;
                     cur.terminalbe=false;
                     return cur.node==0;
    
                }
               //当孩子不存在,结果假,返回假
                if(cur.child[index[*begin ]]==0) return !(result=false);
                else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result)){
                   delete cur.child[index[*begin]];
                   cur.child[index[*begin]]=0;
                   if(--cur.node==0&&cur.terminable==false ) return true;
    
                }
                return false;
    
    
           }
           //根
           node_type root;
           //字符转索引,类似hash
           Index index;
    
    };
    
    class IndexClass{
        public:
            int operator[](const char key){
                return key%26; //一个映射
    
            }
    
    };
    
    
    int main(){
        trie<26,IndexClass> t;
       char s[11];
        //freopen("in.txt","r",stdin);
    
        while(gets(s) && s[0])
        {
            t.insert( s);
        }
    
        while(gets(s))
        {
            printf("%d
    ", t.findNum(s));
        }
    
    
        return 0;
    
    
    }
    


    HDU1671

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    using namespace std;
    #define MAXN 10
    template<int Size>
    struct trie_node
    {
    
        bool terminable; //表示节点为字符串的结尾
        int node;       //子节点的个数
        trie_node *child[Size]; //儿子节点
        trie_node():terminable(false), node(0)
        {
            memset(child,0,sizeof(child)); //初始化节点
        }
    
    };
    template<int Size,typename Index>
    class trie
    {
    public:
        //定义类名
        typedef trie_node<Size> node_type;
        typedef trie_node<Size> *link_type;
    
        //构造函数
        trie(Index i=Index()):index(i) { }
    
        //清空函数,用于析构
        void clear()
        {
            clear_node(root);
            for(int i=0; i<Size; i++)
                root.child[i]=0;
        }
        //插入
        template<typename Iterator>
        void insert(Iterator begin,Iterator end)
        {
            link_type cur= &root;//当前插入结点为根
            while(begin!=end)
            {
                if(cur->child[index[*begin]]) //插入过
                {
                    cur=cur->child[index[*begin]];
                    cur->node++;
    
                }
                else
                {
                    cur->child[index[*begin]]=new node_type;
                    cur->child[index[*begin]]->node++;
                    cur=cur->child[index[*begin]];
    
                }
                begin++; //迭代器往前走!
            }
            cur->terminable=true;
    
        }
    
        //重载c风格插入
        void insert(const char * str)
        {
            insert(str,str+strlen(str));
        }
        
        //插入与判断
        template<typename Iterator>
        bool insert2(Iterator begin,Iterator end)
        {
            link_type cur= &root;//当前插入结点为根
    
             bool flag=0;
            while(begin!=end)
            {
                if(cur->child[index[*begin]]) //插入过
                {
                    if(cur->child[index[*begin]]->terminable==true){
    
    
                        flag=1;
                    }
                    cur=cur->child[index[*begin]];
                    cur->node++;
    
                }
                else
                {
                    cur->child[index[*begin]]=new node_type;
                    cur->child[index[*begin]]->node++;
                    cur=cur->child[index[*begin]];
    
                }
                begin++; //迭代器往前走!
            }
            cur->terminable=true;
            return flag;
    
        }
    
        //重载c风格插入
        bool insert2(const char * str)
        {
            return insert2(str,str+strlen(str));
        }
    
        //查找
        template <typename Iterator>
        bool find(Iterator begin,Iterator end)
        {
            link_type cur=&root;
            while(begin!=end)
            {
    
                if(!cur->child[index[*begin]]) //没有节点啊!!!
                    return false;
                cur=cur->child[index[*begin]];
    
                begin++;
    
            }
            return cur->terminable; //是否为字符串
        }
        //重载c风格
        bool find(const char *str)
        {
    
            return find(str,str+strlen(str));
        }
    
        //查找节点数目
        template <typename Iterator>
        int findNum(Iterator begin,Iterator end)
        {
            link_type cur=&root;
            while(begin!=end)
            {
    
                if(!cur->child[index[*begin]]) //没有节点啊!!!
                    return 0;
                cur=cur->child[index[*begin]];
    
                begin++;
    
            }
    
            return cur->node; //是否为字符串
        }
        //重载c风格
        int findNum(const char *str)
        {
    
            return findNum(str,str+strlen(str));
        }
    
    
    
        //查找前缀
         template <typename Iterator>
        bool findPre(Iterator begin,Iterator end)
        {
            link_type cur=&root;
            while(begin!=end)
            {
    
                if(!cur->child[index[*begin]]) //没有节点啊!!!
                    return false;
    
                if(cur->terminable) break;
                cur=cur->child[index[*begin]];
    
                begin++;
    
            }
            return begin!=end; //是否为字符串
        }
    
        bool findPre(const char *str){
            return findPre(str,str+strlen(str));
    
        }
    
        //删除字符串
        template<typename Iterator>
        bool earse (Iterator begin,Iterator end)
        {
            bool result;
            earse_node(begin,end,root,result);
            return result;
    
    
        }
    
        //c语言风格
        bool erase(char *str)
        {
            return earse(str,str+strlen(str));
    
        }
    
        template<typename Functor>
        void traverse(Functor &execute =Functor())
        {
            visit_node(root,execute);
    
        }
    private:
        //访问结点
        template<typename Functor>
        void visit_node(node_type cur,Functor &execute)
        {
            execute(cur);
            for(int i=0; i<Size; i++) //dfs
            {
                if(cur.child[i]==0) continue;
                visit_node(*cur.child[i],execute);
    
            }
        }
    
        //清空
        void clear_node(node_type cur)
        {
            for(int i=0; i<Size; i++)
            {
                if(cur.child[i]==0)continue; //不存在
                clear_node(*cur.child[i]);
                delete cur.child[i];
                cur.child[i]=0;
                if(--cur.node==0) break; //没有节点了
    
            }
    
        }
    
        //一边搜索一边删除
        template<typename Iterator>
        bool earse_node(Iterator begin ,Iterator end,node_type &cur,bool &result)
        {
            if(begin==end)
            {
                result=cur.terminable;
                cur.terminalbe=false;
                return cur.node==0;
    
            }
            //当孩子不存在,结果假,返回假
            if(cur.child[index[*begin ]]==0) return !(result=false);
            else if(earse_node(begin+1,end,*(cur.child[index[*begin]]),result))
            {
                delete cur.child[index[*begin]];
                cur.child[index[*begin]]=0;
                if(--cur.node==0&&cur.terminable==false ) return true;
    
            }
            return false;
    
    
        }
        //根
        node_type root;
    
    
        //字符转索引,类似hash
        Index index;
    
    };
    
    class IndexClass
    {
    public:
        int operator[](const char key)
        {
            return key%MAXN; //一个映射
    
        }
    
    };
    
    char s[10000][11];
    int main()
    {
        trie<MAXN,IndexClass> t;
    
    
        int T,n,i;
      //  freopen("in.txt","r",stdin);
        scanf("%d",&T);
    
        while(T--)
        {
            scanf("%d",&n);
    
    
            t.clear();
            for(i=0;i<n;i++){
    
                scanf("%s",s[i]);
    
    
                t.insert(s[i]);
    
    
            }
            for(i=0;i<n;i++){
    
    
                if(t.findPre(s[i])){
    
                    puts("NO");
                    break;
                }
            }
            if(i==n) puts("YES");
    
    
    
    
        }
    
    
        return 0;
    
    
    }
    


  • 相关阅读:
    LeetCode 275. H-Index II
    LeetCode 274. H-Index
    LeetCode Gray Code
    LeetCode 260. Single Number III
    LeetCode Word Pattern
    LeetCode Nim Game
    LeetCode 128. Longest Consecutive Sequence
    LeetCode 208. Implement Trie (Prefix Tree)
    LeetCode 130. Surrounded Regions
    LeetCode 200. Number of Islands
  • 原文地址:https://www.cnblogs.com/dengyaolong/p/3697197.html
Copyright © 2011-2022 走看看