zoukankan      html  css  js  c++  java
  • 将C++代码全部写到头文件:)python脚本帮助自动生成相应的实现文件初始框架

    嗯,现在基本没问题了,个人觉得类似python,java那样把类的实现完全写到类里面写起来更方便更快,(当然VC有写类函数的时候利用对话框自动生成实现函数的框架),我把程序放到了google code上:

    http://code.google.com/p/h2cc/

    利用Python脚本可以自动生成相应实现文件。

    使用方法如下: h2cc.py -a a.h

    //a.h 

    int abc();           //函数声明会转换到实现文件中

    int nba() {         //这种函数实现写法默认为在头文件中不变化

      int x = 3; 

    int def()           //这种函数实现写法{在单独一行,会自动转化到实现文件中

    {

      int x = 3; 

     转换之后

    //a.h

     int abc();    

    int nba() {         

      int x = 3; 

    int def() ;         

    //a.cc

    #include "a.h" 

     int abc()

    {

    int def() 

    {

      int x = 3; 

    上面是最简单的示例,对于类和模版类也适用。

    -a 表示会自动将上面的def这样的函数转换,而python3.1 a.h 没有-a选项的话,需要用户标明哪些函数要转到实现文件中,方法是如下的写法加一个多余的;在()后面

     int def() ;

    {

      int x = 3; 

    }

    因为.h文件会变化,所以会备份执行操作前的a.h到a.h.bak.

    另外有一个-t选项,开启-t的话表示处理模版类的情况即如下会加入些别的信息

    在a.h 的namesapce 结束后

    #ifndef A_CC_

    #include "a.cc"

    #endif

    在a.cc文件的开头

    #define A_CC_

    #include "a.h"

    这么做是为了避免循环引用是借鉴Openmesh的做法,对于模版函数的实现用户可以直接实现在.h文件中,现在我只支持分离的写法,这样更清晰些。

    嗯看下实例,我原来将所有的模版类的函数都实现在.h类的定义内部,这样写起来很方便,但是看起来不舒服,希望把实现的部分,分离到.cc中。

    于是调用python3.1 h2cc.py -a -t huff_tree.h  生成合适的huff_tree.cc并适当修改huff_tree.h,所以工作都由h2cc.py自动完成。已验证转换后通过编译链接。

    当然目前不保证有些情况可能会出现未知的bug,那样用户可以参考头文件的拷贝文件.h.bak修正。

    //原来写好的头文件

       1 /* 

      2  * Here use one class for both internal node and leaf.
      3  * This is easier to implement but will cost more space.
      4  *
      5  * For the implementation of differnting internal and leaf
      6  * refering to "A practical introduction to data structure
      7  * and algorithm analisis p 115"
      8  * */
      9 #ifndef _HUFF_TREE_H_
     10 #define _HUFF_TREE_H_  //TODO  automate this for .h file
     11 
     12 #include "type_traits.h"
     13 #include "buffer.h"
     14 #include "assert.h"
     15 #include <queue>
     16 #include <deque>
     17 #include <vector>
     18 #include <functional>
     19 #include <iostream>
     20 namespace glzip{
     21 //----------------------------------------------------------------------------HuffNode------
     22 template <typename _KeyType>
     23 struct HuffNode {
     24   typedef HuffNode<_KeyType>      Node;
     25   ///allow default construct
     26   HuffNode() {}
     27   ///construct a new leaf for character key or string key
     28   HuffNode(_KeyType key, size_t weight = 0
     29       : key_(key), weight_(weight),
     30         left_(NULL), right_(NULL){}
     31   
     32   ///construct a internal leaf from two child
     33   //TODO from const to non const fail
     34   HuffNode(HuffNode* lchild, HuffNode* rchild) 
     35       : left_(lchild), right_(rchild) {
     36     weight_ = lchild->weight() + rchild->weight();
     37   }
     38 
     39   _KeyType key() const{
     40     return key_;
     41   }
     42 
     43   size_t weight() const {
     44     return weight_;
     45   }
     46 
     47   Node* left() const {
     48     return left_;
     49   }
     50 
     51   Node* right() const {
     52     return right_;
     53   }
     54 
     55   bool is_leaf() {
     56     return !left_;  //left_ is NULL means right_ is also,for huf tree it is a full binary tree,every internal node is of degree 2
     57   }
     58   
     59   /////The comparison operator used to order the priority queue.
     60   ////-----But I choose to use the func object for storing pointer in the queuq
     61   ////-----not the Node it's self, TODO see the performance differnce 
     62   //bool operator > (const HuffNode& other) const {
     63   //  return weight > other.weight;
     64   //}
     65   
     66   //-------------------------------------------------------------------
     67   _KeyType  key_;
     68   size_t    weight_;   //here weight is frequency of char or string 
     69   Node*     left_;
     70   Node*     right_;
     71 };
     72 
     73 //-----------------------------------------------HuffTree-------------------HuffTreeBase----
     74 /**
     75  * For HuffTree
     76  * It take the frequency_map_ and encode_map_ as input.
     77  * Those two are not owned by HuffTree but HuffEncoder.
     78  * HuffTree will use frequence_map_ info to make encode_map_ ok.
     79  * 1. Wait until frequency_map_ is ready (which is handled by HuffEncoder)
     80  * 2. build_tree()  
     81  * 3. gen_encode()
     82  * 4. serialize_tree()
     83  * The sequence is important can not break!
     84  *
     85  * TODO(Array based HuffTree) actually the hufftree can be implemented using simple array do
     86  * not need building the tree.
     87  *
     88  * TODO For string type the tree might be so big, the rec is OK?
     89  * */
     90 template <typename _KeyType>
     91 class HuffTreeBase {
     92 public:
     93   typedef HuffNode<_KeyType>       Node;
     94 public:
     95   void set_root(Node* other) {
     96     root_ = other;
     97   }
     98 
     99   void delete_tree(Node* root) { //TODO rec what if the tree is so big?
    100     if (root) {
    101       delete_tree(root->left());
    102       delete_tree(root->right());
    103       delete root;
    104     }
    105   }
    106  
    107   //for test
    108   void travel(Node* root) {
    109     if (root) {
    110       travel(root->left());
    111       travel(root->right());
    112     }
    113   }
    114 
    115   Node* root() const {
    116     return root_;
    117   }
    118 protected:
    119   Node*   root_;
    120 };
    121 
    122 //---------------------------------------------------------------------------HuffTree for encode---
    123 template <typename _KeyType, typename _TreeType = encode_hufftree>
    124 class HuffTree: public HuffTreeBase<_KeyType> {
    125 public:
    126   using HuffTreeBase<_KeyType>::root;
    127   using HuffTreeBase<_KeyType>::set_root;
    128   using HuffTreeBase<_KeyType>::delete_tree;
    129 
    130   typedef typename TypeTraits<_KeyType>::type_catergory             type_catergory;
    131   typedef typename TypeTraits<_KeyType>::FrequencyHashMap           FrequencyHashMap;
    132   typedef typename TypeTraits<_KeyType>::EncodeHashMap              EncodeHashMap;
    133   typedef HuffNode<_KeyType>                                        Node;
    134   
    135   struct HuffNodePtrGreater:
    136       public std::binary_function<const Node *const Node *bool> {
    137     
    138     bool operator() (const Node *p1, const Node *p2) {
    139       return p1->weight() > p2->weight();
    140     }
    141   };
    142   //typedef std::deque<Node> HuffDQU;   //TODO use vector to see which is better and why
    143   //typedef std::priority_queue<Node,HuffDQU, greater<Node> >         HuffPRQUE; //desending order use less<HuffNode> if asending
    144   typedef std::deque<Node*> HuffDQU;   //TODO use vector to see which is better and why
    145   typedef std::priority_queue<Node*, HuffDQU, HuffNodePtrGreater>     HuffPRQUE; //desending order use less<HuffNode> if asending
    146 
    147 public:
    148   HuffTree(EncodeHashMap& encode_map, FrequencyHashMap& frequency_map)  //long long int (&)[256] can not be inited by const long 
    149         : encode_map_(encode_map), frequency_map_(frequency_map) 
    150   {  
    151     build_tree();        //assmue frequency_map is ready when creating the tree        
    152   }  
    153   ~HuffTree() {
    154     //std::cout << "dstruct hufftree\n";
    155     delete_tree(root());
    156   }
    157   void gen_encode() {
    158     std::string encode;
    159     do_gen_encode(root(), encode);   
    160     //std::cout << "Finished encoding\n";
    161   }
    162   void build_tree() 
    163   {
    164     init_queue(type_catergory());
    165     int times = pqueue_.size() - 1;
    166     for (int i = 0; i < times; i++) {
    167       Node* lchild = pqueue_.top();
    168       pqueue_.pop();
    169       Node* rchild = pqueue_.top();
    170       pqueue_.pop();
    171       Node* p_internal = new Node(lchild, rchild);
    172       pqueue_.push(p_internal);
    173     }
    174     set_root(pqueue_.top());  
    175     //std::cout << "Finished building tree\n"; 
    176   }
    177 
    178   ///write the header info to the outfile, for decompressor to rebuild the tree
    179   //----write in pre order travelling
    180   void serialize_tree(FILE* outfile) {
    181     Buffer writer(outfile);  //the input outfile cur should be at 0
    182     do_serialize_tree(root(), writer);
    183     writer.flush_buf();   //make sure writting to the file
    184   }
    185 private:
    186   void init_queue(char_tag) {
    187     for(int i = 0; i < 256; i++) {
    188       if (frequency_map_[i]) {
    189         Node* p_leaf = new Node(i, frequency_map_[i]); //key is i and weight is frequency_map_[i]
    190         pqueue_.push(p_leaf);        //push leaf
    191       }
    192     }
    193   }
    194 
    195   //TODO try to use char[256] to speed up!
    196    void do_gen_encode(Node* root, std::string& encode) 
    197    {
    198     if (root->is_leaf()) {
    199       encode_map_[root->key()] = encode;
    200       return;
    201     }
    202     encode.append("0");              //TODO how string operation is implemented what is the effecience??
    203     do_gen_encode(root->left(), encode);
    204     encode[encode.size() - 1= '1';
    205     do_gen_encode(root->right(), encode);
    206     encode.erase(encode.size() - 11);
    207   }
    208 
    209   //void do_gen_encode(Node* root, std::string encode) {
    210   //  //if (root->is_leaf()) {
    211   //  //if (root->left() == NULL || root->right() == NULL) {
    212   //  //  //encode_map_[root->key()] = encode;
    213   //  //  return;
    214   //  //}
    215   //  if (!root->right() && !root->left())
    216   //    return;
    217   //  do_gen_encode(root->left(), encode + "0");
    218   //  do_gen_encode(root->right(), encode + "1");
    219   //}
    220 
    221 
    222   //serialize like (1, 1), (1, 1), (0, 'a').
    223   void do_serialize_tree(Node* root, Buffer& writer) 
    224   {
    225     if (root->is_leaf()) {
    226       writer.write_byte(0);  //0 means the leaf
    227       writer.write_byte(root->key());  //write the key
    228       return;
    229     }
    230     writer.write_byte(255);  //255 means the internal node
    231     writer.write_byte(255);  //any num is ok
    232     do_serialize_tree(root->left(), writer);
    233     do_serialize_tree(root->right(), writer);
    234   }
    235 
    236   //----------------------------------------------------for string_tag--------
    237   void init_queue(string_tag) {
    238     
    239   }
    240 private:
    241   HuffPRQUE              pqueue_;
    242   EncodeHashMap&         encode_map_;
    243   FrequencyHashMap&      frequency_map_;
    244 };
    245 
    246 //---------------------------------------------------------------------------HuffTree for decode---
    247 /** Specitialized HuffTree for decoding*/
    248 template <typename _KeyType>
    249 class HuffTree<_KeyType, decode_hufftree>
    250     : public HuffTreeBase<_KeyType>{
    251 public:
    252   using HuffTreeBase<_KeyType>::root;
    253   using HuffTreeBase<_KeyType>::root_;
    254   using HuffTreeBase<_KeyType>::set_root;
    255   using HuffTreeBase<_KeyType>::delete_tree;
    256   typedef HuffNode<_KeyType>  Node;
    257 
    258 public:
    259   HuffTree(FILE* infile, FILE* outfile)
    260       :infile_(infile), outfile_(outfile),
    261        reader_(infile) {} 
    262 
    263   ~HuffTree() {
    264     delete_tree(root());
    265   }
    266 
    267   ///build_tree() is actually get_encode_info()
    268   void build_tree() {  //From the infile header info we can build the tree
    269     do_build_tree(root_);
    270   }
    271  
    272   //help debug to see if the tree rebuild from file is the same as the intial one
    273   void do_gen_encode(Node* root, std::string& encode) 
    274   {
    275     if (root->is_leaf()) {
    276       std::cout << root->key() << " " << encode << "\n";
    277       return;
    278     }
    279     encode.append("0");              //TODO how string operation is implemented what is the effecience??
    280     do_gen_encode(root->left(), encode);
    281     encode[encode.size() - 1= '1';
    282     do_gen_encode(root->right(), encode);
    283     encode.erase(encode.size() - 11);
    284   }
    285 
    286   void decode_file();
    287 private:
    288   void do_build_tree(Node*& root) 
    289   {
    290     unsigned char first, second;
    291     reader_.read_byte(first);
    292     reader_.read_byte(second);
    293     if (first == 0) {  //is leaf  TODO actually we do not need weight this time so HuffNode can be smaller
    294       root = new Node(second);
    295       return;
    296     }
    297     root = new Node();
    298     do_build_tree(root->left_);
    299     do_build_tree(root->right_);
    300   }
    301 
    302   void decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num = 8);
    303   FILE*  infile_;
    304   FILE*  outfile_;
    305   Buffer reader_;   //need reader_ becuause for two function build_tree and decode_file we need the same reader
    306 };
    307 
    308 }   //end of space glzip
    309 

     //h2cc.py自动修改的头文件

      1 /* 
      2  * Here use one class for both internal node and leaf.
      3  * This is easier to implement but will cost more space.
      4  *
      5  * For the implementation of differnting internal and leaf
      6  * refering to "A practical introduction to data structure
      7  * and algorithm analisis p 115"
      8  * */
      9 #ifndef _HUFF_TREE_H_
     10 #define _HUFF_TREE_H_  //TODO  automate this for .h file
     11 
     12 #include "type_traits.h"
     13 #include "buffer.h"
     14 #include "assert.h"
     15 #include <queue>
     16 #include <deque>
     17 #include <vector>
     18 #include <functional>
     19 #include <iostream>
     20 namespace glzip{
     21 //----------------------------------------------------------------------------HuffNode------
     22 template <typename _KeyType>
     23 struct HuffNode {
     24   typedef HuffNode<_KeyType>      Node;
     25   ///allow default construct
     26   HuffNode() {}
     27   ///construct a new leaf for character key or string key
     28   HuffNode(_KeyType key, size_t weight = 0
     29       : key_(key), weight_(weight),
     30         left_(NULL), right_(NULL){}
     31   
     32   ///construct a internal leaf from two child
     33   //TODO from const to non const fail
     34   HuffNode(HuffNode* lchild, HuffNode* rchild) 
     35       : left_(lchild), right_(rchild) {
     36     weight_ = lchild->weight() + rchild->weight();
     37   }
     38 
     39   _KeyType key() const{
     40     return key_;
     41   }
     42 
     43   size_t weight() const {
     44     return weight_;
     45   }
     46 
     47   Node* left() const {
     48     return left_;
     49   }
     50 
     51   Node* right() const {
     52     return right_;
     53   }
     54 
     55   bool is_leaf() {
     56     return !left_;  //left_ is NULL means right_ is also,for huf tree it is a full binary tree,every internal node is of degree 2
     57   }
     58   
     59   /////The comparison operator used to order the priority queue.
     60   ////-----But I choose to use the func object for storing pointer in the queuq
     61   ////-----not the Node it's self, TODO see the performance differnce 
     62   //bool operator > (const HuffNode& other) const {
     63   //  return weight > other.weight;
     64   //}
     65   
     66   //-------------------------------------------------------------------
     67   _KeyType  key_;
     68   size_t    weight_;   //here weight is frequency of char or string 
     69   Node*     left_;
     70   Node*     right_;
     71 };
     72 
     73 //-----------------------------------------------HuffTree-------------------HuffTreeBase----
     74 /**
     75  * For HuffTree
     76  * It take the frequency_map_ and encode_map_ as input.
     77  * Those two are not owned by HuffTree but HuffEncoder.
     78  * HuffTree will use frequence_map_ info to make encode_map_ ok.
     79  * 1. Wait until frequency_map_ is ready (which is handled by HuffEncoder)
     80  * 2. build_tree()  
     81  * 3. gen_encode()
     82  * 4. serialize_tree()
     83  * The sequence is important can not break!
     84  *
     85  * TODO(Array based HuffTree) actually the hufftree can be implemented using simple array do
     86  * not need building the tree.
     87  *
     88  * TODO For string type the tree might be so big, the rec is OK?
     89  * */
     90 template <typename _KeyType>
     91 class HuffTreeBase {
     92 public:
     93   typedef HuffNode<_KeyType>       Node;
     94 public:
     95   void set_root(Node* other) {
     96     root_ = other;
     97   }
     98 
     99   void delete_tree(Node* root) { //TODO rec what if the tree is so big?
    100     if (root) {
    101       delete_tree(root->left());
    102       delete_tree(root->right());
    103       delete root;
    104     }
    105   }
    106  
    107   //for test
    108   void travel(Node* root) {
    109     if (root) {
    110       travel(root->left());
    111       travel(root->right());
    112     }
    113   }
    114 
    115   Node* root() const {
    116     return root_;
    117   }
    118 protected:
    119   Node*   root_;
    120 };
    121 
    122 //---------------------------------------------------------------------------HuffTree for encode---
    123 template <typename _KeyType, typename _TreeType = encode_hufftree>
    124 class HuffTree: public HuffTreeBase<_KeyType> {
    125 public:
    126   using HuffTreeBase<_KeyType>::root;
    127   using HuffTreeBase<_KeyType>::set_root;
    128   using HuffTreeBase<_KeyType>::delete_tree;
    129 
    130   typedef typename TypeTraits<_KeyType>::type_catergory             type_catergory;
    131   typedef typename TypeTraits<_KeyType>::FrequencyHashMap           FrequencyHashMap;
    132   typedef typename TypeTraits<_KeyType>::EncodeHashMap              EncodeHashMap;
    133   typedef HuffNode<_KeyType>                                        Node;
    134   
    135   struct HuffNodePtrGreater:
    136       public std::binary_function<const Node *const Node *bool> {
    137     
    138     bool operator() (const Node *p1, const Node *p2) {
    139       return p1->weight() > p2->weight();
    140     }
    141   };
    142   //typedef std::deque<Node> HuffDQU;   //TODO use vector to see which is better and why
    143   //typedef std::priority_queue<Node,HuffDQU, greater<Node> >         HuffPRQUE; //desending order use less<HuffNode> if asending
    144   typedef std::deque<Node*> HuffDQU;   //TODO use vector to see which is better and why
    145   typedef std::priority_queue<Node*, HuffDQU, HuffNodePtrGreater>     HuffPRQUE; //desending order use less<HuffNode> if asending
    146 
    147 public:
    148   HuffTree(EncodeHashMap& encode_map, FrequencyHashMap& frequency_map)  //long long int (&)[256] can not be inited by const long 
    149         : encode_map_(encode_map), frequency_map_(frequency_map) 
    150   {  
    151     build_tree();        //assmue frequency_map is ready when creating the tree        
    152   }  
    153   ~HuffTree() {
    154     //std::cout << "dstruct hufftree\n";
    155     delete_tree(root());
    156   }
    157   void gen_encode() {
    158     std::string encode;
    159     do_gen_encode(root(), encode);   
    160     //std::cout << "Finished encoding\n";
    161   }
    162   void build_tree();
    163   ///write the header info to the outfile, for decompressor to rebuild the tree
    164   //----write in pre order travelling
    165   void serialize_tree(FILE* outfile) {
    166     Buffer writer(outfile);  //the input outfile cur should be at 0
    167     do_serialize_tree(root(), writer);
    168     writer.flush_buf();   //make sure writting to the file
    169   }
    170 private:
    171   void init_queue(char_tag) {
    172     for(int i = 0; i < 256; i++) {
    173       if (frequency_map_[i]) {
    174         Node* p_leaf = new Node(i, frequency_map_[i]); //key is i and weight is frequency_map_[i]
    175         pqueue_.push(p_leaf);        //push leaf
    176       }
    177     }
    178   }
    179 
    180   //TODO try to use char[256] to speed up!
    181    void do_gen_encode(Node* root, std::string& encode);
    182   //void do_gen_encode(Node* root, std::string encode) {
    183   //  //if (root->is_leaf()) {
    184   //  //if (root->left() == NULL || root->right() == NULL) {
    185   //  //  //encode_map_[root->key()] = encode;
    186   //  //  return;
    187   //  //}
    188   //  if (!root->right() && !root->left())
    189   //    return;
    190   //  do_gen_encode(root->left(), encode + "0");
    191   //  do_gen_encode(root->right(), encode + "1");
    192   //}
    193 
    194 
    195   //serialize like (1, 1), (1, 1), (0, 'a').
    196   void do_serialize_tree(Node* root, Buffer& writer);
    197   //----------------------------------------------------for string_tag--------
    198   void init_queue(string_tag) {
    199     
    200   }
    201 private:
    202   HuffPRQUE              pqueue_;
    203   EncodeHashMap&         encode_map_;
    204   FrequencyHashMap&      frequency_map_;
    205 };
    206 
    207 //---------------------------------------------------------------------------HuffTree for decode---
    208 /** Specitialized HuffTree for decoding*/
    209 template <typename _KeyType>
    210 class HuffTree<_KeyType, decode_hufftree>
    211     : public HuffTreeBase<_KeyType>{
    212 public:
    213   using HuffTreeBase<_KeyType>::root;
    214   using HuffTreeBase<_KeyType>::root_;
    215   using HuffTreeBase<_KeyType>::set_root;
    216   using HuffTreeBase<_KeyType>::delete_tree;
    217   typedef HuffNode<_KeyType>  Node;
    218 
    219 public:
    220   HuffTree(FILE* infile, FILE* outfile)
    221       :infile_(infile), outfile_(outfile),
    222        reader_(infile) {} 
    223 
    224   ~HuffTree() {
    225     delete_tree(root());
    226   }
    227 
    228   ///build_tree() is actually get_encode_info()
    229   void build_tree() {  //From the infile header info we can build the tree
    230     do_build_tree(root_);
    231   }
    232  
    233   //help debug to see if the tree rebuild from file is the same as the intial one
    234   void do_gen_encode(Node* root, std::string& encode);
    235   void decode_file();
    236 private:
    237   void do_build_tree(Node*& root);
    238   void decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num = 8);
    239   FILE*  infile_;
    240   FILE*  outfile_;
    241   Buffer reader_;   //need reader_ becuause for two function build_tree and decode_file we need the same reader
    242 };
    243 
    244 }   //end of space glzip
    245 #ifndef HUFF_TREE_CC_
    246 #include "huff_tree.cc"
    247 #endif
    248 #endif  //------------end of _HUFF_TREE_H_

    249  

     //h2cc.py自动生成的实现文件

      1 #define HUFF_TREE_CC_
      2 #include "huff_tree.h"
      3 
      4 namespace glzip{
      5 
      6 template <typename _KeyType>
      7 void HuffTree<_KeyType, decode_hufftree>::decode_file()
      8 {
      9   Buffer writer(outfile_);
     10   unsigned char left_bit, last_byte;
     11   reader_.read_byte(left_bit);
     12   reader_.read_byte(last_byte);
     13   //--------------------------------------decode each byte
     14   Node* cur_node = root();
     15   unsigned char c;
     16   while(reader_.read_byte(c)) 
     17     decode_byte(c, writer, cur_node);
     18   //--------------------------------------deal with the last byte
     19   if (left_bit)
     20     decode_byte(last_byte, writer, cur_node, (8 - left_bit));
     21   writer.flush_buf();
     22   fflush(outfile_);
     23 }
     24 
     25 
     26 template <typename _KeyType>
     27 void HuffTree<_KeyType, decode_hufftree>::
     28 decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num)
     29 {
     30   unsigned char mask = 128//1 << 7
     31   for (int i = 0; i < bit_num; i++) {
     32     if ((c & mask) == 0)  //--------------bit i of c is 0,turn left
     33       cur_node = cur_node->left_;
     34     else
     35       cur_node = cur_node->right_;
     36     mask >>= 1;
     37     if (cur_node->is_leaf()) {
     38       writer.write_byte(cur_node->key_);
     39       cur_node = root();
     40     }
     41   }
     42 }
     43 
     44 template <typename _KeyType, typename _TreeType>
     45 void HuffTree<_KeyType, _TreeType>::build_tree()
     46 {
     47   init_queue(type_catergory());
     48   int times = pqueue_.size() - 1;
     49   for (int i = 0; i < times; i++) {
     50     Node* lchild = pqueue_.top();
     51     pqueue_.pop();
     52     Node* rchild = pqueue_.top();
     53     pqueue_.pop();
     54     Node* p_internal = new Node(lchild, rchild);
     55     pqueue_.push(p_internal);
     56   }
     57   set_root(pqueue_.top());  
     58   //std::cout << "Finished building tree\n"; 
     59 }
     60 
     61 
     62 //TODO try to use char[256] to speed up!
     63 template <typename _KeyType, typename _TreeType>
     64 void HuffTree<_KeyType, _TreeType>::
     65 do_gen_encode(Node* root, std::string& encode)
     66 {
     67  if (root->is_leaf()) {
     68    encode_map_[root->key()] = encode;
     69    return;
     70  }
     71  encode.append("0");              //TODO how string operation is implemented what is the effecience??
     72  do_gen_encode(root->left(), encode);
     73  encode[encode.size() - 1= '1';
     74  do_gen_encode(root->right(), encode);
     75  encode.erase(encode.size() - 11);
     76   }
     77 
     78 
     79 //serialize like (1, 1), (1, 1), (0, 'a').
     80 template <typename _KeyType, typename _TreeType>
     81 void HuffTree<_KeyType, _TreeType>::
     82 do_serialize_tree(Node* root, Buffer& writer)
     83 {
     84   if (root->is_leaf()) {
     85     writer.write_byte(0);  //0 means the leaf
     86     writer.write_byte(root->key());  //write the key
     87     return;
     88   }
     89   writer.write_byte(255);  //255 means the internal node
     90   writer.write_byte(255);  //any num is ok
     91   do_serialize_tree(root->left(), writer);
     92   do_serialize_tree(root->right(), writer);
     93 }
     94 
     95 
     96 //help debug to see if the tree rebuild from file is the same as the intial one
     97 template <typename _KeyType>
     98 void HuffTree<_KeyType, decode_hufftree>::
     99 do_gen_encode(Node* root, std::string& encode)
    100 {
    101   if (root->is_leaf()) {
    102     std::cout << root->key() << " " << encode << "\n";
    103     return;
    104   }
    105   encode.append("0");              //TODO how string operation is implemented what is the effecience??
    106   do_gen_encode(root->left(), encode);
    107   encode[encode.size() - 1= '1';
    108   do_gen_encode(root->right(), encode);
    109   encode.erase(encode.size() - 11);
    110 }
    111 
    112 
    113 template <typename _KeyType>
    114 void HuffTree<_KeyType, decode_hufftree>::
    115 do_build_tree(Node*& root)
    116 {
    117   unsigned char first, second;
    118   reader_.read_byte(first);
    119   reader_.read_byte(second);
    120   if (first == 0) {  //is leaf  TODO actually we do not need weight this time so HuffNode can be smaller
    121     root = new Node(second);
    122     return;
    123   }
    124   root = new Node();
    125   do_build_tree(root->left_);
    126   do_build_tree(root->right_);
    127 }
    128 
    129 }   //end of space glzip
    130 
    131 

    132  

  • 相关阅读:
    怎样才有资格被称为开源软件
    [翻译]开发Silverlight 2.0的自定义控件
    网上Silverlight项目收集
    Google 分析的基准化测试
    IIS 承载的WCF服务失败
    Lang.NET 2008 相关Session
    Silverlight 2.0 beta1 堆栈
    asp.net 性能调较
    SQL Server 2005 的nvarchar(max),varchar(max)来救火
    LINQPad
  • 原文地址:https://www.cnblogs.com/rocketfan/p/1589871.html
Copyright © 2011-2022 走看看