Trie的C++实现及HDU1251,hdu1671

35 篇文章 0 订阅
13 篇文章 0 订阅
#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\n", 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;


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值