Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

116 líneas
2.8KB

  1. #include <iostream>
  2. #include <map>
  3. #include <queue>
  4. #include <string>
  5. using namespace std; // import namespace std
  6. // There are no general binary trees in the STL.
  7. // But we do not use much of this structure anyhow...
  8. struct node {
  9. struct node *left;
  10. struct node *right;
  11. char symbol;
  12. int weight;
  13. node (char c, int i) { // leaf constructor
  14. symbol = c;
  15. weight = i;
  16. left = right = 0;
  17. }
  18. node (node* l, node *r) { // internal node constructor
  19. symbol = 0;
  20. weight = l->weight + r->weight;
  21. left = l;
  22. right = r;
  23. }
  24. bool isleaf() {return symbol!=0;}
  25. bool operator> (const node &a) const {
  26. return weight > a.weight;
  27. }
  28. };
  29. // construct the Huffman trie for this message
  30. node* huffman_trie (string message) {
  31. // count multiplicities
  32. map<char,int> cmap;
  33. for (string::iterator i=message.begin(); i!=message.end(); i++)
  34. if (cmap.find(*i)!=cmap.end())
  35. cmap[*i]++;
  36. else
  37. cmap[*i]=1;
  38. // generate leaves with multiplicities
  39. priority_queue<node, vector<node>, greater<node> > q;
  40. for (map<char,int>::iterator i=cmap.begin(); i!=cmap.end(); i++)
  41. q.push(node(i->first,i->second));
  42. // build Huffman tree (trie)
  43. while (q.size()>1)
  44. {
  45. node *left = new node(q.top());
  46. q.pop();
  47. node *right = new node(q.top());
  48. q.pop();
  49. q.push(node(left, right));
  50. }
  51. return new node(q.top());
  52. }
  53. // recursive filling of the encoding table 'code'
  54. void fill_encoding_table (string s, node *i,
  55. map<char,string>& code) {
  56. if (i->isleaf())
  57. code[i->symbol]=s;
  58. else
  59. {
  60. fill_encoding_table (s+"0", i->left, code);
  61. fill_encoding_table (s+"1", i->right, code);
  62. }
  63. }
  64. // encoding
  65. string encode (map<char,string> code, string& message) {
  66. string encoded = "";
  67. for (string::iterator i=message.begin(); i!=message.end(); i++)
  68. encoded += code[*i];
  69. return encoded;
  70. }
  71. // decoding
  72. string decode (node* trie, string& encoded) {
  73. string decoded = "";
  74. node* node = trie;
  75. for (string::iterator i=encoded.begin(); i!=encoded.end(); i++)
  76. {
  77. if (!node->isleaf())
  78. node = (*i=='0') ? node->left : node->right;
  79. if (node->isleaf())
  80. {
  81. decoded.push_back(node->symbol);
  82. node = trie;
  83. }
  84. }
  85. return decoded;
  86. }
  87. int main () {
  88. string message = "ABRACADABRASIMSALABIM";
  89. // generate Huffman trie
  90. node* trie = huffman_trie(message);
  91. // generate and show encoding table
  92. map<char,string> table;
  93. fill_encoding_table ("", trie, table);
  94. for (map<char,string>::iterator i=table.begin(); i!=table.end(); i++)
  95. cout << i->first << " " << i->second << endl;
  96. // encode and decode
  97. string encoded = encode(table, message);
  98. cout << "Encoded: " << encoded <<
  99. " [" << encoded.size() << " Bits]" << endl ;
  100. cout << "Decoded: " << decode(trie, encoded) << endl;
  101. // the trie is not deleted here ...
  102. }