Gilgamesh858

Huffman.cpp

Feb 9th, 2016
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | None | 0 0
  1. #include <iostream>
  2. #include <ctime>
  3. #include <math.h>
  4. #include <string.h>
  5. using namespace std;
  6. #define MAX 256
  7.  
  8. template <class T> class Node {
  9.     private:
  10.         T key;
  11.         int value;
  12.         Node<T> *left, *right;
  13.         int leaf;
  14.     public:
  15.         Node<T>(T key) {
  16.             this->key = key;
  17.             left = right = NULL;
  18.             leaf = 1;
  19.         }
  20.         T getKey() {return key;}
  21.         int isLeaf() {return leaf;}
  22.         int getValue() {return value;}
  23.         Node<T>* getLeft() {return left;}
  24.         Node<T>* getRight() {return right;}
  25.         void setKey(T key) {this->key = key;}
  26.         void setLeaf(int leaf) {this->leaf = leaf;}
  27.         void setValue(int value) {this->value = value;}
  28.         void incValue() {this->value++;}
  29.         void setLeft(Node<T>* left) {this->left = left;}
  30.         void setRight(Node<T>* right) {this->right = right;}
  31. };
  32.  
  33. template <class T> class BinaryTree {
  34.     private:
  35.         int size;
  36.         Node<T> *root;
  37.     public:
  38.         BinaryTree<T>(T x) {
  39.             root = new Node<T>(x);
  40.             size = 1;
  41.         }
  42.         BinaryTree<T>(BinaryTree<T> *a, BinaryTree<T> *b, T x) {
  43.             root = new Node<T>(x);
  44.             size = a->getSize() + b->getSize() + 1;    
  45.             root->setLeft(a->getRoot());
  46.             root->setRight(b->getRoot());
  47.             root->setLeaf(0);
  48.         }
  49.         int getSize() {return size;}
  50.         Node<T>* getRoot() {return root;}
  51. };
  52.  
  53. class Code {
  54.     private:
  55.         int c;
  56.         int len;
  57.     public:
  58.         Code(int len) {
  59.             c = 0;
  60.             this->len = len;
  61.         }
  62.         Code(int len, int mask) {
  63.             c = mask;
  64.             this->len = len;
  65.         }
  66.         void setBit(int i) {
  67.             int mask = 1 << i;
  68.             c = c|mask;
  69.         }
  70.         void unsetBit(int i) {
  71.             int mask = 1 << i;
  72.             mask = ~mask;
  73.             c = c & mask;
  74.         }
  75.         int getBit(int i) {
  76.             int mask = 1;
  77.             return (c>>i)&mask;
  78.         }
  79.         void print() {
  80.             for(int i=0; i<len; i++)
  81.                 cout << getBit(i);
  82.             cout << endl;
  83.         }
  84. };
  85.  
  86. class Huffman {
  87.     private:
  88.         BinaryTree<char> *T;
  89.         Code *HT[MAX];
  90.         int alpha;
  91.        
  92.         int getFreq(BinaryTree<char> *t) {
  93.             if(t==NULL) return 0;
  94.             return t->getRoot()->getValue();
  95.         }
  96.        
  97.         void reverseOrder(BinaryTree<char> *S[], int n) {
  98.             for(int i=1; i<n; i++) {
  99.                 int j = i;
  100.                 while(j>0 && getFreq(S[j])>getFreq(S[j-1])) {
  101.                     BinaryTree<char> *temp = S[j];
  102.                     S[j] = S[j-1];
  103.                     S[j-1] = temp;
  104.                     j--;
  105.                 }
  106.             }
  107.         }
  108.        
  109.         BinaryTree<char> *computeHuffmanTree(char *text, int n) {
  110.             int freq[MAX];
  111.             for(int i=0; i<MAX; i++) freq[i] = 0;
  112.             alpha = 0;
  113.             for(int i=0; i<n; i++) {
  114.                 if(freq[text[i]]==0) {
  115.                     alpha++;
  116.                 }
  117.                 freq[text[i]]++;
  118.             }
  119.            
  120.             BinaryTree<char> *TreeSet[MAX];
  121.             for(int i=0; i<MAX; i++) TreeSet[i] = NULL;
  122.             int j = 0;
  123.             for(int i=0; i<MAX; i++)
  124.                 if(freq[i]>0) {
  125.                     TreeSet[j] = new BinaryTree<char>((char)i);
  126.                     TreeSet[j]->getRoot()->setValue(freq[i]);
  127.                     j++;
  128.                 }
  129.            
  130.             reverseOrder(TreeSet, alpha);
  131.             j = alpha-1;
  132.             while(j>0) {
  133.                 BinaryTree<char> *a = TreeSet[j-1];
  134.                 BinaryTree<char> *b = TreeSet[j];
  135.                 BinaryTree<char> *c = new BinaryTree<char>(a,b,'@');
  136.                 c->getRoot()->setValue(getFreq(a)+getFreq(b));
  137.                 TreeSet[j-1] = c;
  138.                 TreeSet[j] = NULL;
  139.                 int k = j-1;
  140.                 while(k>0 && getFreq(TreeSet[k])>getFreq(TreeSet[k-1])) {
  141.                     BinaryTree<char> *temp = TreeSet[k];
  142.                     TreeSet[k] = TreeSet[k-1];
  143.                     TreeSet[k-1] = temp;
  144.                     k--;
  145.                 }
  146.                 j--;
  147.             }
  148.            
  149.             for(int i = 0; i<alpha; i++)
  150.                 if(TreeSet[i]!=NULL)
  151.                     cout << TreeSet[i]->getRoot()->getKey() << ": " << getFreq(TreeSet[i]) <<endl;
  152.  
  153.             return TreeSet[0];
  154.         }
  155.  
  156.         void visitTree(Node<char>* t, int mask, int len) {
  157.             if(t==NULL) return;
  158.             //cout << t->getKey() << endl;
  159.             if(t->isLeaf()) {
  160.                 HT[t->getKey()] = new Code(len, mask);
  161.                 return;
  162.             }
  163.             visitTree(t->getLeft(), mask, len+1);
  164.             mask = mask | (1<<(len));
  165.             visitTree(t->getRight(), mask, len+1);
  166.         }
  167.        
  168.     public:
  169.         Huffman(char *text, int n) {
  170.             for(int i=0; i<MAX; i++) HT[i] = NULL;
  171.             T = computeHuffmanTree(text, n);
  172.             int mask = 0;
  173.             visitTree(T->getRoot(), mask, 0);
  174.         }
  175.        
  176.         void printHT() {
  177.             for(int i=0; i<MAX; i++) {
  178.                 if(HT[i]!=NULL) {
  179.                     cout << (char)i << ": ";
  180.                     HT[i]->print();
  181.                 }
  182.             }
  183.         }
  184. };
  185.  
  186.  
  187. int main() {
  188.     char prova[] = "questo rappresenta un testo di prova";
  189.     int n = strlen(prova);
  190.     Huffman *H = new Huffman(prova,n);
  191.     H->printHT();
  192.     return 1;
  193. }
Add Comment
Please, Sign In to add comment