Advertisement
Guest User

Longest Common Subsequence implementation

a guest
Sep 12th, 2014
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.17 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <map>
  6. #include <queue>
  7. #include <utility>
  8. #include <ctime>
  9. #include <cstdlib>
  10. #include <boost/smart_ptr.hpp>
  11. #include <boost/cstdint.hpp>
  12.  
  13. template <typename Iterator>
  14. size_t generalized_hash(Iterator begin, const Iterator &end){
  15.     size_t ret = 0xF00BA8;
  16.     const size_t factor =
  17. #ifdef _M_X64
  18.         0x8BADF00DDEADBEEF;
  19. #else
  20.         0xDEADBEEF;
  21. #endif
  22.     for (; begin != end; ++begin){
  23.         ret *= factor;
  24.         ret ^= *begin;
  25.     }
  26.     return ret;
  27. }
  28.  
  29. size_t hash_string(const std::string &s){
  30.     return generalized_hash(s.begin(), s.end());
  31. }
  32.  
  33.  
  34. class fast_string{
  35.     std::string s;
  36.     size_t hash;
  37.     int unique;
  38. public:
  39.     fast_string(const std::string &s): s(), hash(hash_string(s)), unique(0){}
  40.     fast_string(const fast_string &fs): s(fs.s), hash(fs.hash), unique(fs.unique){}
  41.     bool operator==(const fast_string &s) const{
  42.         return !(this->s != s.s);
  43.     }
  44.     bool operator!=(const fast_string &s) const{
  45.         return this->hash != s.hash || this->s != s.s;
  46.     }
  47.     const std::string &get_string() const{
  48.         return this->s;
  49.     }
  50.     void set_unique(int where){
  51.         this->unique = where;
  52.     }
  53.     int get_unique() const{
  54.         return this->unique;
  55.     }
  56.     operator size_t() const{
  57.         return this->hash;
  58.     }
  59. };
  60.  
  61. template <typename T>
  62. class generalized_set{
  63.     typedef typename std::vector<T>::const_iterator it_t;
  64.     it_t begin, end;
  65.     size_t hash;
  66.     int unique;
  67. public:
  68.     generalized_set(const it_t &begin, const it_t &end): begin(begin), end(end), hash(generalized_hash(begin, end)), unique(0){}
  69.     generalized_set(const generalized_set &gs): begin(gs.begin), end(gs.end), hash(gs.hash), unique(gs.unique){}
  70.     bool operator==(const generalized_set<T> &gs) const{
  71.         return !(*this != gs);
  72.     }
  73.     bool operator!=(const generalized_set<T> &gs) const{
  74.         if (this->hash != gs.hash)
  75.             return 1;
  76.         auto i = this->begin, j = gs.begin;
  77.         for (; i != this->end && j != gs.end; ++i, ++j){
  78.             if (*i != *j)
  79.                 return 1;
  80.         }
  81.         return i == this->end || j == gs.end;
  82.     }
  83.     void set_unique(int where){
  84.         this->unique = where;
  85.     }
  86.     int get_unique() const{
  87.         return this->unique;
  88.     }
  89. };
  90.  
  91. typedef std::pair<int, int> key_t;
  92.  
  93. struct coord{
  94.     int x, y;
  95.     coord(): x(0), y(0){}
  96. };
  97.  
  98. class lcs_result;
  99.  
  100. typedef boost::shared_ptr<lcs_result> ptr;
  101.  
  102. #ifdef _DEBUG
  103. #define vassert(x) if (!(x)) __debugbreak()
  104. #else
  105. #define vassert
  106. #endif
  107.  
  108. class lcs_result{
  109.     ptr child;
  110. public:
  111.     void set_child(const ptr &p){
  112.         int d = -1;
  113.         bool goal;
  114.         if (p){
  115.             d = p->distance;
  116.             goal = p->goal;
  117.         }
  118.         this->child = p;
  119.         if (d >= 0){
  120.             this->distance = d + 1;
  121.             this->goal = goal;
  122.         }
  123.     }
  124.     ptr get_child(){
  125.         return this->child;
  126.     }
  127.     enum Arrow{
  128.         UP_LEFT,
  129.         LEFT,
  130.         UP,
  131.         ANY
  132.     };
  133.     Arrow type;
  134.     int length;
  135.     int distance;
  136.     bool goal;
  137.     coord initial,
  138.         final;
  139.     static volatile unsigned long long live_instances;
  140.     lcs_result(): type(ANY), length(0), distance(0), goal(0){
  141.         this->live_instances++;
  142.     }
  143.     ~lcs_result(){
  144.         //vassert(!(!this->initial.x && !this->initial.y));
  145.         this->live_instances--;
  146.         std::vector<ptr> v;
  147.         ptr p = this->child;
  148.         this->child.reset();
  149.         while (p){
  150.             vassert(p.use_count() >= 1);
  151.             if (p.use_count() > 1)
  152.                 break;
  153.             v.push_back(p);
  154.             auto copy = p->child;
  155.             p->child.reset();
  156.             p = copy;
  157.         }
  158.     }
  159.     void set_coord(int x, int y){
  160.         this->initial.x = x;
  161.         this->initial.y = y;
  162.         this->final.x = x;
  163.         this->final.y = y;
  164.         if (!x && !y)
  165.             this->goal = 1;
  166.     }
  167.     bool try_merge(){
  168.         if (!this->child)
  169.             return 0;
  170.         if (this->type != this->child->type)
  171.             return 0;
  172.         if (this->child.use_count() > 1)
  173.             return 0;
  174.         this->initial = this->child->initial;
  175.         if (this->type == UP_LEFT)
  176.             this->length++;
  177.         this->set_child(this->child->child);
  178.         return 1;
  179.     }
  180.     bool operator<(const lcs_result &b) const{
  181.         if (this->length < b.length)
  182.             return 1;
  183.         //if (this->distance > b.distance)
  184.         //  return 1;
  185.         //if (!this->goal && b.goal)
  186.         //  return 1;
  187.         return 0;
  188.     }
  189.     bool operator>(const lcs_result &b) const{
  190.         return b < *this;
  191.     }
  192. };
  193.  
  194. volatile unsigned long long lcs_result::live_instances = 0;
  195.  
  196. typedef std::map<std::pair<int, int>, lcs_result> table_t;
  197.  
  198. template <typename T>
  199. lcs_result *lcs_b(const std::vector<T> &x, const std::vector<T> &y, int i, int j, ptr up, ptr left, ptr up_left){
  200.     auto res = new lcs_result;
  201.     if (i < 0 || j < 0){
  202.         res->type = lcs_result::LEFT;
  203.         res->length = 0;
  204.         res->set_coord(i, j);
  205.         return res;
  206.     }
  207.     if (x[i] == y[j]){
  208.         res->type = lcs_result::UP_LEFT;
  209.         res->set_child(up_left);
  210.         res->length = (up_left ? up_left->length : 0) + 1;
  211.     }else{
  212.         ptr a = left;
  213.         ptr b = up;
  214.         if (!left && !up){
  215.             res->type = lcs_result::LEFT;
  216.             res->length = 0;
  217.         }else{
  218.             if (left && (!up || up && *left > *up)){
  219.                 res->type = lcs_result::LEFT;
  220.                 res->set_child(left);
  221.                 res->length = left->length;
  222.             }else if (up && (!left || left && *left < *up)){
  223.                 res->type = lcs_result::UP;
  224.                 res->set_child(up);
  225.                 res->length = up->length;
  226.             }else{
  227.                 res->length = left->length;
  228.                 res->set_child(left);
  229.                 res->type = lcs_result::LEFT;
  230.             }
  231.         }
  232.     }
  233.     res->set_coord(i, j);
  234.     return res;
  235. }
  236.  
  237. template <typename T>
  238. T deref(std::vector<T> *v, int index){
  239.     if (index < 0 || (size_t)index >= v->size())
  240.         return T();
  241.     return (*v)[index];
  242. }
  243.  
  244. template <typename T>
  245. ptr lcs_length(const std::vector<T> &x, const std::vector<T> &y){
  246.     //std::map<std::pair<int, int>, lcs_result> table;
  247.     int h = y.size();
  248.     int w = x.size();
  249.     int x0 = 0;
  250.     int y1 = 0;
  251.     auto stack0 = new std::vector<ptr>,
  252.         last_stack0 = new std::vector<ptr>,
  253.         stack1 = new std::vector<ptr>,
  254.         last_stack1 = new std::vector<ptr>;
  255.     for (int i = 1;;){
  256.         bool any = 0;
  257.         /*
  258.         if (i == 23){
  259.             for (size_t i = 0; i < stack0->size(); i++){
  260.                 auto p = (*stack0)[i];
  261.                 for (auto p2 = p; p2; p2 = p2->get_child()){
  262.                     if (!p2->initial.x && !p2->initial.y)
  263.                         __debugbreak();
  264.                 }
  265.             }
  266.         }
  267.         */
  268.         stack0->clear();
  269.         stack0->reserve(i / 2);
  270.         for (int y0 = 0; y0 < i / 2; y0++){
  271.             if ((size_t)x0 >= x.size() || (size_t)y0 >= y.size())
  272.                 break;
  273.             auto left = deref(last_stack0, y0);
  274.             if (x0 - 1 == y0 && last_stack1->size()){
  275.                 left = last_stack1->back();
  276.             }
  277.             auto node = lcs_b(x, y , x0, y0, deref(stack0, y0 - 1), left, deref(last_stack0, y0 - 1));
  278.             stack0->push_back(ptr(node));
  279.             any = 1;
  280.         }
  281.         x0++;
  282.         i++;
  283.         stack1->clear();
  284.         stack1->reserve(i / 2);
  285.         for (int x1 = 0; x1 < i / 2; x1++){
  286.             if ((size_t)x1 >= x.size() || (size_t)y1 >= y.size())
  287.                 break;
  288.             auto up = deref(last_stack1, x1);
  289.             if (x1 == y1 && stack0->size()){
  290.                 up = stack0->back();
  291.             }
  292.             auto node = lcs_b(x, y , x1, y1, up, deref(stack1, x1 - 1), deref(last_stack1, x1 - 1));
  293.             stack1->push_back(ptr(node));
  294.             any = 1;
  295.         }
  296.         y1++;
  297.         i++;
  298.         if (!any)
  299.             break;
  300.         for (auto p : *stack0){
  301.             if (!p || !p->get_child())
  302.                 continue;
  303.             p->get_child()->try_merge();
  304.         }
  305.         for (auto p : *stack1){
  306.             if (!p || !p->get_child())
  307.                 continue;
  308.             p->get_child()->try_merge();
  309.         }
  310.         std::swap(stack0, last_stack0);
  311.         std::swap(stack1, last_stack1);
  312.     }
  313.     ptr res;
  314.     if (last_stack0->size() > last_stack1->size())
  315.         res = last_stack0->back();
  316.     else
  317.         res = last_stack1->back();
  318.     last_stack0->clear();
  319.     last_stack1->clear();
  320.     for (ptr i = res; i; i = i->get_child())
  321.         while (i->try_merge());
  322.     /*
  323.     for (ptr i = res; i; i = i->get_child()){
  324.         switch (i->type){
  325.             case lcs_result::LEFT:
  326.             case lcs_result::ANY:
  327.                 std::cout <<"left";
  328.                 break;
  329.             case lcs_result::UP:
  330.                 std::cout <<"up";
  331.                 break;
  332.             case lcs_result::UP_LEFT:
  333.                 std::cout <<"up-left";
  334.                 break;
  335.         }
  336.         std::cout <<" ("<<i->initial.x<<"-"<<i->final.x<<", "<<i->initial.y<<"-"<<i->final.y<<")\n";
  337.     }
  338.     */
  339.     return res;
  340. }
  341.  
  342. template <typename T>
  343. std::vector<T> lcs_b(const std::vector<T> &x, const std::vector<T> &y, int i, int j, ptr lookup){
  344.     std::vector<T> ret;
  345.     assert(lookup->final.x == i && lookup->final.y == j);
  346.     while (i >= 0 && j >= 0){
  347.         switch (lookup->type){
  348.             case lcs_result::LEFT:
  349.                 while (i >= lookup->initial.x){
  350.                     T insert = x[i];
  351.                     insert.set_unique(-1);
  352.                     ret.push_back(insert);
  353.                     i--;
  354.                 }
  355.                 break;
  356.             case lcs_result::UP:
  357.                 while (j >= lookup->initial.y){
  358.                     T insert = y[j];
  359.                     insert.set_unique(1);
  360.                     ret.push_back(insert);
  361.                     j--;
  362.                 }
  363.                 break;
  364.             case lcs_result::UP_LEFT:
  365.                 while (i >= lookup->initial.x){
  366.                     ret.push_back(x[i]);
  367.                     i--;
  368.                     j--;
  369.                 }
  370.                 break;
  371.             default:
  372.                 assert(0);
  373.         }
  374.         lookup = lookup->get_child();
  375.     }
  376.     while (j >= 0){
  377.         T insert = y[j];
  378.         insert.set_unique(1);
  379.         ret.push_back(insert);
  380.         j--;
  381.     }
  382.     while (i >= 0){
  383.         T insert = x[i];
  384.         insert.set_unique(-1);
  385.         ret.push_back(insert);
  386.         i--;
  387.     }
  388.     std::reverse(ret.begin(), ret.end());
  389.     return ret;
  390. }
  391.  
  392. template <typename T>
  393. std::vector<T> lcs_b(const std::vector<T> &x, const std::vector<T> &y){
  394.     auto lcs_lookup = lcs_length(x, y);
  395.     return lcs_b(x, y, x.size() - 1, y.size() - 1, lcs_lookup);
  396. }
  397.  
  398. std::vector<fast_string> read_file(const char *path){
  399.     std::ifstream file(path);
  400.     std::vector<fast_string> ret;
  401.     ret.reserve(150000);
  402.     while (1){
  403.         std::string line;
  404.         std::getline(file, line);
  405.         if (!file)
  406.             break;
  407.         ret.push_back(line);
  408.     }
  409.     for (int i = ret.size(); ret.size() < 150000; i++)
  410.         ret.push_back(ret[((size_t)pow(i, 3.14159265)) % ret.size()]);
  411.     return ret;
  412. }
  413.  
  414. template <typename T>
  415. std::vector<generalized_set<T> > split_vector(const std::vector<T> &v){
  416.     std::vector<generalized_set<T> > ret;
  417.     auto last = v.begin();
  418.     const size_t split_size = 64;
  419.     for (size_t i = 0; ; i += split_size){
  420.         if (i + split_size > v.size()){
  421.             ret.push_back(generalized_set<T>(last, v.end()));
  422.             break;
  423.         }
  424.         auto first = last;
  425.         last += split_size;
  426.         ret.push_back(generalized_set<T>(first, last));
  427.     }
  428.     return ret;
  429. }
  430.  
  431. int main(){
  432.     std::vector<fast_string> string0 = read_file("0.txt"),
  433.         string1 = read_file("1.txt");
  434.     auto v0 = split_vector(string0);
  435.     auto v1 = split_vector(string1);
  436.     for (const auto l : lcs_b(v0, v1)){
  437.         int unique = l.get_unique();
  438.         if (unique < 0)
  439.             std::cout <<"(<=)\n";
  440.         else if (unique > 0)
  441.             std::cout <<"(=>)\n";
  442.         else
  443.             std::cout <<"(==)\n";
  444.         //std::cout <<l.get_string()<<std::endl;
  445.     }
  446. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement