Guest User

Untitled

a guest
Jun 24th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.15 KB | None | 0 0
  1. /* Created by: Justin Meiners (2017) */
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <string>
  7. #include <tuple>
  8. #include <sstream>
  9.  
  10. void add_frequency(std::string text, int* frequency_table)
  11. {
  12. for (auto i = text.begin(); i != text.end(); ++i)
  13. {
  14. unsigned char char_index = static_cast<unsigned char>(*i);
  15. frequency_table[char_index] += 1;
  16. }
  17. }
  18.  
  19. template <typename X, typename Y>
  20. struct compare_second
  21. {
  22. bool operator()(const std::pair<X, Y>& a, const std::pair<X, Y>& b) const
  23. {
  24. return a.second < b.second;
  25. }
  26. };
  27.  
  28. struct huff_tree
  29. {
  30. typedef short index_type;
  31.  
  32. struct node
  33. {
  34. node() : key('\0'), left(-1), right(-1) {}
  35. node(unsigned char key) : key(key), left(-1), right(-1) {}
  36.  
  37. unsigned char key;
  38. index_type left;
  39. index_type right;
  40. };
  41.  
  42. short head;
  43. std::vector<node> nodes;
  44. std::vector<std::string> lookup_table;
  45.  
  46. huff_tree() : head(-1) {}
  47.  
  48. static void build_lookup_table(huff_tree& t, int node_index, const std::string& prefix)
  49. {
  50. const node& n = t.nodes[node_index];
  51. if (n.left == -1 && n.right == -1)
  52. {
  53. t.lookup_table[n.key] = prefix;
  54. }
  55. else
  56. {
  57. build_lookup_table(t, n.left, prefix + '0');
  58. build_lookup_table(t, n.right, prefix + '1');
  59. }
  60. }
  61.  
  62. static huff_tree build(const int* frequency_table)
  63. {
  64. huff_tree t;
  65. auto cmp = compare_second<index_type, int>();
  66. std::vector< std::pair<index_type, int> > heap;
  67.  
  68. for (int i = 0; i < 255; ++i)
  69. {
  70. if (frequency_table[i] == 0)
  71. continue;
  72.  
  73. index_type index = static_cast<index_type>(t.nodes.size());
  74. heap.push_back(std::make_pair(index, frequency_table[i]));
  75.  
  76. unsigned char character = static_cast<unsigned char>(i);
  77. t.nodes.push_back(node(character));
  78. }
  79.  
  80. std::make_heap(heap.begin(), heap.end(), cmp);
  81.  
  82. while (heap.size() > 1)
  83. {
  84. node new_node;
  85. auto x = std::min_element(heap.begin(), heap.end(), cmp);
  86. int sum = (*x).second;
  87. new_node.left = (*x).first;
  88. heap.erase(x);
  89.  
  90. auto y = std::min_element(heap.begin(), heap.end(), cmp);
  91. sum += (*y).second;
  92. new_node.right = (*y).first;
  93. heap.erase(y);
  94.  
  95. index_type new_node_index = static_cast<index_type>(t.nodes.size());
  96. t.nodes.push_back(new_node);
  97.  
  98. heap.push_back(std::make_pair(new_node_index, sum));
  99. std::push_heap(heap.begin(), heap.end(), cmp);
  100. }
  101.  
  102. t.head = heap.front().first;
  103. t.lookup_table.resize(255);
  104. build_lookup_table(t, t.head, std::string());
  105.  
  106. return t;
  107. }
  108.  
  109. void print_node(index_type node_index, int indent) const
  110. {
  111. const auto& n = nodes[node_index];
  112. std::cout << std::setw(indent);
  113. std::cout << n.key << std::endl;
  114.  
  115. if (n.left != -1)
  116. print_node(n.left, indent);
  117.  
  118. if (n.right != -1)
  119. print_node(n.right, indent + 2);
  120. }
  121.  
  122. void print() const
  123. {
  124. print_node(head, 0);
  125. }
  126. };
  127.  
  128.  
  129. void simple_test()
  130. {
  131.  
  132. int frequency_table[255];
  133. memset(frequency_table, 0, sizeof(frequency_table));
  134.  
  135. frequency_table['A'] = 5;
  136. frequency_table['B'] = 2;
  137. frequency_table['C'] = 3;
  138. frequency_table['D'] = 4;
  139. frequency_table['E'] = 10;
  140. frequency_table['F'] = 1;
  141.  
  142. auto tree = huff_tree::build(frequency_table);
  143. tree.print();
  144. }
  145.  
  146. int main(int argc, const char* argv[])
  147. {
  148. int line_count = 0;
  149. int frequency_table[255];
  150. memset(frequency_table, 0, sizeof(frequency_table));
  151.  
  152. std::string line;
  153. while (std::getline(std::cin, line))
  154. {
  155. add_frequency(line, frequency_table);
  156. ++line_count;
  157. }
  158.  
  159. auto tree = huff_tree::build(frequency_table);
  160.  
  161. for (int i = 0; i < 255; ++i)
  162. {
  163. if (tree.lookup_table[i].size() == 0)
  164. continue;
  165. std::cout << static_cast<unsigned char>(i) << ": ";
  166. std::cout << tree.lookup_table[i] << std::endl;
  167. }
  168.  
  169. return 1;
  170. }
Add Comment
Please, Sign In to add comment