Advertisement
thexiv

Compression

Feb 7th, 2021 (edited)
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.86 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <math.h>
  4. #include <sstream>
  5. #include <string.h>
  6. #include <unistd.h>
  7.  
  8. using namespace std;
  9.  
  10. struct nodes {
  11.     public:
  12.     bool x = 0;
  13.     nodes * left = nullptr;
  14.     nodes * right = nullptr;
  15.     nodes(bool x): x(x), left(nullptr), right(nullptr) {};
  16. } *tail, *head;
  17.  
  18. stringstream out;
  19.  
  20. uint64_t TIMES_DEEP = 0, outsize = 0;
  21.  
  22. string large_num;
  23.  
  24. void parsebst(nodes * node, int32_t p, string current_num, bool t);
  25. void printbst();
  26. nodes * front(nodes*& node, uint64_t entry);
  27. int pack(fstream& fout);
  28.  
  29. void parsebst(nodes * node, int32_t p, string current_num, bool t)
  30. {
  31.     if (node->left == nullptr && node->right == nullptr)
  32.         return;
  33.  
  34.     uint8_t counter = 0;
  35.  
  36.     if (node->right != nullptr) {
  37.         if (p < 0)
  38.         {
  39.             if (p > 3)
  40.                 cout << "." << flush;
  41.             p = abs(p);
  42.             current_num += to_string(t);
  43.             for (int g = 0 ; g < 2 ; g++)
  44.             {
  45.                 large_num += to_string(p%2);
  46.                 p >>= 1;
  47.             }
  48.             large_num += current_num;
  49.             current_num = "";
  50.         }
  51.         p++;
  52.         current_num += (node->x) ? "1" : "0";
  53.         parsebst(node->right, p, current_num, 0);
  54.  
  55.     }
  56.     if (node->left != nullptr)
  57.     {
  58.         if (p > 0)
  59.         {
  60.             if (p < -3)
  61.                 cout << "." << flush;
  62.             p = abs(p);
  63.             current_num += to_string(t);
  64.             for (int g = 0 ; g < 2 ; g++)
  65.             {
  66.                 large_num += to_string(p%2);
  67.                 p >>= 1;
  68.             }
  69.             large_num += current_num;
  70.             current_num = "";
  71.         }
  72.         p--;
  73.         current_num += (node->x) ? "1" : "0";
  74.         parsebst(node->left, p, current_num, 1);
  75.     }
  76.  
  77. }
  78.  
  79. void printbst() {
  80.  
  81.     while (large_num.length() > 7)
  82.     {
  83.         if (strtoull(large_num.substr(0,7).c_str(),NULL,2) == 0)
  84.             out << (char)('\0');
  85.         else
  86.             out << (char)strtoull(large_num.substr(0,8).c_str(),NULL,2);
  87.         large_num = large_num.substr(7);
  88.     }
  89.  
  90.     large_num += "00000000";
  91.  
  92.     if (strtoull(large_num.c_str(),NULL,2) == 0)
  93.         out << (char)('\0');
  94.     else
  95.         out << (char)strtoull(large_num.c_str(),NULL,2);
  96.  
  97.     large_num.clear();
  98.  
  99.     return;
  100. }
  101.  
  102.  
  103. nodes * erase_node(nodes*& node){
  104.  
  105.     if (node->left != nullptr)
  106.         node = erase_node(node->left);
  107.     else if (node->right != nullptr)
  108.         node = erase_node(node->right);
  109.  
  110.     free(node);
  111.  
  112.     return NULL;
  113. }
  114.  
  115. nodes * front(nodes*& node, uint64_t entry){
  116.  
  117.     if (entry == 0)
  118.         return node;
  119.  
  120.     TIMES_DEEP++;
  121.  
  122.     if (node->left != nullptr)
  123.         front(node->left, entry);
  124.     else if (node->right != nullptr)
  125.         front(node->right,entry);
  126.  
  127.     if (entry%4 >= 2) {
  128.         node->left = new nodes(entry%2);
  129.         entry >>= 2;
  130.         front(node->left, entry);
  131.     }
  132.     else if (entry%4 <= 1) {
  133.         node->right = new nodes(entry%2);
  134.         entry >>= 2;
  135.         front(node->right, entry);
  136.     }
  137.     return node;
  138.  
  139. }
  140.  
  141. int pack(fstream& fout) {
  142.  
  143.     TIMES_DEEP = 0;
  144.  
  145.     if (head->left != nullptr)
  146.         parsebst(head, 0, "", 0);
  147.     else if (head->right != nullptr)
  148.         parsebst(head, 0, "", 1);
  149.  
  150.     printbst();
  151.  
  152.     out << "|x|";
  153.     outsize += out.str().length();
  154.     fout << out.str();
  155.     out.str("");
  156.  
  157.  
  158.     return 1;
  159. }
  160.  
  161. int main(int argc, char * argv[])
  162. {
  163.  
  164.     fstream fin (argv[2], std::ios::in | std::ios::binary);
  165.  
  166.     stringstream sstring;
  167.     stringstream sstring_out;
  168.     sstring << fin.rdbuf();
  169.     string g = "", h = sstring.str();
  170.     sstring.str("");
  171.  
  172.     fstream fout (argv[3], std::ios::out | std::ios::trunc | std::ios::binary);
  173.     tail = new nodes(0);
  174.     uint64_t d = 1, cnter = 0, place = 0;
  175.     string thx = "thank you! so much!!";
  176.     string f = "";
  177.     cout << "Input size: " << (h.length()) << endl << flush;
  178.     uint64_t file_size = h.length();
  179.     uint64_t TIMES_OVER = 90;
  180.  
  181.     for (uint32_t a = 1; a <= h.length() ; a++)
  182.     {
  183.         d <<= 8;
  184.         place++;
  185.         if (a%3000 == 0 || a == h.length())
  186.             printf("%.0f%%\t\t%.0f%% \t\r",(double)a/(double)h.length()*100,(double)outsize/(double)(a)*100);
  187.         if (a%6 == 5 || a == h.length())
  188.         {
  189.             if (h[a-1] != '\0')
  190.                d += (uint8_t)h[a-1];
  191.         }
  192.         else
  193.             continue;
  194.  
  195.  
  196.         if (head == nullptr)
  197.             head = new nodes(0);
  198.         *tail = &head;
  199.         front(tail, d);
  200.         d = 1;
  201.  
  202.         if (TIMES_DEEP >= TIMES_OVER || a == h.length())
  203.         {
  204.             pack(fout);
  205.             erase_node(head);
  206.         }
  207.     }
  208.  
  209.     printf("%.0f%%\t\t%.0f%% \t\r",(double)place/(double)h.length()*100,(double)outsize/(double)place*100);
  210.     cout << "\nOutput size: " << outsize << endl << flush;
  211.     return 0;
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement