Advertisement
MohsenTamiz

A dummy trie

Feb 17th, 2016
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.02 KB | None | 0 0
  1. #ifndef TREE_HH
  2. #define TREE_HH
  3.  
  4. #include <utility>
  5.  
  6. #include <boost/serialization/export.hpp>
  7. #include <boost/serialization/tracking.hpp>
  8. #include <boost/serialization/split_member.hpp>
  9. #include <boost/serialization/utility.hpp>
  10. #include <boost/serialization/base_object.hpp>
  11. #include <boost/preprocessor/tuple/enum.hpp>
  12.  
  13. #include <unordered_map>
  14. #include <iostream>
  15.  
  16. using namespace std;
  17.  
  18. #define FOO_CLASS_TRACKING(E, PARAMETER_TUPLE, ...)             \
  19.   namespace boost {                                             \
  20.   namespace serialization {                                     \
  21.   template<BOOST_PP_TUPLE_ENUM(PARAMETER_TUPLE)>                \
  22.   struct tracking_level< __VA_ARGS__ >                          \
  23.   {                                                             \
  24.     typedef mpl::integral_c_tag tag;                            \
  25.     typedef mpl::int_< E> type;                                 \
  26.     BOOST_STATIC_CONSTANT(                                      \
  27.                           int,                                  \
  28.                           value = tracking_level::type::value   \
  29.                                              );                 \
  30.     /* tracking for a class  */                                 \
  31.     BOOST_STATIC_ASSERT((                                       \
  32.                          mpl::greater<                          \
  33.                          /* that is a prmitive */               \
  34.                          implementation_level< __VA_ARGS__ >,   \
  35.                          mpl::int_<primitive_type>              \
  36.                          >::value                               \
  37.                                              ));                \
  38.   };                                                            \
  39.   }}
  40.  
  41. namespace Tree
  42. {
  43.  
  44. class NodeInterface
  45. {
  46. public:
  47.   NodeInterface()
  48.   {}
  49.  
  50.   virtual NodeInterface *get_child(const uint8_t i) const = 0;
  51.  
  52.   virtual NodeInterface *set_child(const uint8_t i) = 0;
  53.   virtual void set_child(const uint8_t i, NodeInterface *child) = 0;
  54.   virtual NodeInterface *upgrade() = 0;
  55.  
  56.   virtual void print(int indention = 0) const = 0;
  57.  
  58.   template <typename Archive>
  59.   void save(Archive &ar, const unsigned int version) const
  60.   {
  61.   }
  62.  
  63.   template <typename Archive>
  64.   void load(Archive &ar, const unsigned int version)
  65.   {
  66.   }
  67.  
  68.   BOOST_SERIALIZATION_SPLIT_MEMBER()
  69.  
  70.   friend class boost::serialization::access;
  71.  
  72.   virtual ~NodeInterface()
  73.   {}
  74. };
  75.  
  76. template <uint8_t num_elem = 1>
  77. class Node;
  78.  
  79. template<uint8_t num_elem>
  80. NodeInterface *upgrade_node(const Node<num_elem> &node)
  81. {
  82.   return new Node<num_elem + 1>;
  83. }
  84.  
  85. template<>
  86. NodeInterface *upgrade_node(const Node<10> &node)
  87. {
  88.   return nullptr;
  89. }
  90.  
  91. template<uint8_t num_elem>
  92. class Node : public NodeInterface
  93. {
  94. public:
  95.   Node():
  96.     NodeInterface()
  97.   {
  98.     for (int i = 0; i < num_elem; ++i)
  99.       children[i] = make_pair(0, nullptr);
  100.   }
  101.  
  102.   pair<uint8_t, NodeInterface*> children[num_elem];
  103.  
  104.   NodeInterface *get_child(const uint8_t in) const override
  105.   {
  106.     assert(in < 10);
  107.     for (int i = 0; i < num_elem; ++i)
  108.     {
  109.       if (children[i].second && children[i].first == in)
  110.       {
  111.         return children[i].second;
  112.       }
  113.     }
  114.  
  115.     return nullptr;
  116.   }
  117.  
  118.   NodeInterface *set_child(const uint8_t in) override
  119.   {
  120.     assert(in < 10);
  121.  
  122.     for (int i = 0; i < num_elem; ++i)
  123.     {
  124.       if (children[i].second == nullptr)
  125.       {
  126.         auto new_node = new Node;
  127.         children[i] = make_pair(in, new_node);
  128.  
  129.         return new_node;
  130.       }
  131.     }
  132.  
  133.     return nullptr;
  134.   }
  135.  
  136.   void set_child(const uint8_t in, NodeInterface *child) override
  137.   {
  138.     assert(in < 10);
  139.     for (int i = 0; i < num_elem; ++i)
  140.     {
  141.       if (children[i].first == in)
  142.       {
  143.         delete children[i].second;
  144.         children[i].second = child;
  145.         return;
  146.       }
  147.       else if (children[i].second == nullptr)
  148.       {
  149.         children[i] = make_pair(in, child);
  150.         return;
  151.       }
  152.     }
  153.   }
  154.  
  155.   void print(int indention = 0) const override
  156.   {
  157.     string indent_str(indention, ' ');
  158.  
  159.     for (auto & child : children)
  160.     {
  161.       if (child.second)
  162.       {
  163.         cout << indent_str << ": " << to_string(child.first) << endl;
  164.         child.second->print(indention + 2);
  165.       }
  166.     }
  167.   }
  168.  
  169.   NodeInterface *upgrade() override
  170.   {
  171.     auto new_node = upgrade_node(*this);
  172.     if (new_node)
  173.     {
  174.       for (int i = 0; i < num_elem; ++i)
  175.       {
  176.         new_node->set_child(children[i].first, children[i].second);
  177.         children[i].second = nullptr;
  178.       }
  179.     }
  180.  
  181.     return new_node;
  182.   }
  183.  
  184.   template <typename Archive>
  185.   void save(Archive &ar, const unsigned int version) const
  186.   {
  187.     ar & boost::serialization::base_object<NodeInterface>(*this);
  188.  
  189.     ar & children;
  190.   }
  191.  
  192.   template <typename Archive>
  193.   void load(Archive &ar, const unsigned int version)
  194.   {
  195.     ar & boost::serialization::base_object<NodeInterface>(*this);
  196.     ar & children;
  197.   }
  198.  
  199.   BOOST_SERIALIZATION_SPLIT_MEMBER()
  200.  
  201.   friend class boost::serialization::access;
  202.  
  203.   ~Node()
  204.   {
  205.     for (int i = 0; i < num_elem; ++i)
  206.     {
  207.       if (children[i].second)
  208.         delete children[i].second;
  209.     }
  210.   }
  211. };
  212.  
  213. class Tree
  214. {
  215. public:
  216.   NodeInterface *root;
  217.  
  218.   Tree():
  219.     root(new Node<>)
  220.   {}
  221.  
  222.   void insert(size_t i)
  223.   {
  224.     auto last_s = root;
  225.     auto s = root;
  226.  
  227.     uint32_t last_i = i;
  228.     auto temp = root;
  229.  
  230.     while ((temp = s->get_child(i%10)))
  231.     {
  232.       last_s = s;
  233.       last_i = i;
  234.       s = temp;
  235.       i /= 10;
  236.     }
  237.  
  238.     while (i > 0)
  239.     {
  240.       auto temp = s->set_child(i % 10);
  241.  
  242.       if (temp == nullptr)
  243.       {
  244.         if (s == root)
  245.         {
  246.           s = s->upgrade();
  247.           delete root;
  248.           root = s;
  249.           last_s = root;
  250.         }
  251.         else
  252.         {
  253.           s = s->upgrade();
  254.           last_s->set_child(last_i % 10, s);
  255.         }
  256.  
  257.         last_s = s;
  258.         s = s->set_child(i % 10);
  259.       }
  260.       else
  261.       {
  262.         last_s = s;
  263.         s = temp;
  264.       }
  265.  
  266.       last_i = i;
  267.       i /= 10;
  268.     }
  269.   }
  270.  
  271.   void print() const
  272.   {
  273.     root->print();
  274.   }
  275.  
  276.   template <typename Archive>
  277.   void save(Archive &ar, const unsigned int version) const
  278.   {
  279.     ar & root;
  280.   }
  281.  
  282.   template <typename Archive>
  283.   void load(Archive &ar, const unsigned int version)
  284.   {
  285.     ar & root;
  286.   }
  287.  
  288.   BOOST_SERIALIZATION_SPLIT_MEMBER()
  289.  
  290.   friend class boost::serialization::access;
  291.  
  292.   ~Tree()
  293.   {
  294.     delete root;
  295.   }
  296.  
  297. };
  298. } // Tree namepspace
  299.  
  300. BOOST_CLASS_EXPORT(Tree::Node<1>)
  301. BOOST_CLASS_EXPORT(Tree::Node<2>)
  302. BOOST_CLASS_EXPORT(Tree::Node<3>)
  303. BOOST_CLASS_EXPORT(Tree::Node<4>)
  304. BOOST_CLASS_EXPORT(Tree::Node<5>)
  305. BOOST_CLASS_EXPORT(Tree::Node<6>)
  306. BOOST_CLASS_EXPORT(Tree::Node<7>)
  307. BOOST_CLASS_EXPORT(Tree::Node<8>)
  308. BOOST_CLASS_EXPORT(Tree::Node<9>)
  309. BOOST_CLASS_EXPORT(Tree::Node<10>)
  310. BOOST_CLASS_TRACKING(Tree::NodeInterface, boost::serialization::track_never)
  311. FOO_CLASS_TRACKING(boost::serialization::track_never, (uint8_t num_elem), Tree::Node<num_elem>)
  312. FOO_CLASS_TRACKING(boost::serialization::track_never, (), pair<const uint8_t, Tree::NodeInterface*>)
  313.  
  314. #endif /* TREE_HH */
  315.  
  316. ================= main.cc =======================
  317.  
  318. #include "tree.hh"
  319.  
  320. #include <boost/archive/binary_iarchive.hpp>
  321. #include <boost/archive/binary_oarchive.hpp>
  322.  
  323. #include <fstream>
  324.  
  325. #define MAX_NUM 10000000
  326.  
  327. int main(int argc, char *argv[])
  328. {
  329.   Tree::Tree tree;
  330.  
  331.   for (int i = 0; i < MAX_NUM; ++i)
  332.     tree.insert(i);
  333.  
  334.   const char* text_file_name = "/tmp/tree.txt";
  335.   {
  336.     std::ofstream ofs(text_file_name, ios::binary | ios::out);
  337.     std::filebuf *fb = ofs.rdbuf();
  338.  
  339.     boost::archive::binary_oarchive ar(*fb, boost::archive::no_tracking);
  340.     cout << "Start serialization..." << endl;
  341.     ar & tree;
  342.     cout << "Serialization done." << endl;
  343.   }
  344.  
  345.   // {
  346.   //   std::ifstream ifs(text_file_name);
  347.  
  348.   //   boost::archive::binary_iarchive ar(ifs);
  349.  
  350.   //   Tree::Tree tree1;
  351.  
  352.   //   ar & tree1;
  353.  
  354.   //   tree1.print();
  355.   // }
  356.  
  357.   return 0;
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement