Advertisement
Guest User

Untitled

a guest
Apr 20th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.10 KB | None | 0 0
  1. /*Cameron Dobbs - 11697123
  2. **CS101 - Spring 2018
  3. **Project 4 - This project reads a plain text file, computes a Huffman code tree for that text file, and writes out the encoded version of the text.
  4. */
  5.  
  6. #include <iostream>
  7. #include <fstream>
  8. #include <string>
  9. using namespace std;
  10.  
  11.  
  12. struct treenode {
  13.         //leaf as a node
  14.         char letter;
  15.         int occurences;
  16.         treenode *left;
  17.         treenode *right;
  18. };
  19.  
  20. void heapify(treenode *minheap, int passNum, int i, treenode move) {
  21.         treenode temp;
  22.         int left = (2*i)+1;
  23.         int right = (2*i)+2;
  24.  
  25.         cout << "passNum = " << passNum << endl;
  26.  
  27.         //node you are inserting is bigger than left child, swap them. go again with the new move
  28.         if (minheap[left].occurences <= minheap[right].occurences) {
  29.                 if ((left <= passNum) && (minheap[left].occurences < move.occurences)) {
  30.                 temp = move;
  31.                 minheap[i] = minheap[left];
  32.                 minheap[left] = temp;
  33.                 for (int m = 0; m < passNum + 1; m++) {
  34.                         cout << "heapifyL: node: " << minheap[m].letter << " ...occur: " << minheap[m].occurences << endl;
  35.                 }
  36.                 cout << endl;
  37.                 heapify(minheap, passNum, left, minheap[left]);
  38.                 }
  39.         }
  40.         else if (minheap[right].occurences < minheap[left].occurences) {
  41.                 if ((right <= passNum) && (minheap[right].occurences < move.occurences)) {
  42.                 temp = move;
  43.                 minheap[i] = minheap[right];
  44.                 minheap[right] = temp;
  45.                 for (int m = 0; m < passNum + 1; m++) {
  46.                         cout << "heapifyR: node: " << minheap[m].letter << " ...occur: " << minheap[m].occurences << endl;
  47.                 }
  48.                 cout << endl;
  49.                 heapify(minheap, passNum, right, minheap[right]);
  50.                 }
  51.         }
  52. }
  53.  
  54. //extracts the top node, replaces it with the last, then reorders
  55. treenode *extractMin(treenode *minheap, int &passNum) {
  56.         treenode *min = new treenode;
  57.         *min = minheap[0];
  58.  
  59.         minheap[0] = minheap[passNum];
  60.  
  61.  
  62.         passNum -= 1;
  63.  
  64.         //put in huffman tree...buble it down - the first one ...compare with two children, swap if out of order...go until it stops
  65.         heapify(minheap, passNum, 0, minheap[0]);
  66.  
  67.         return min;
  68. }
  69.  
  70.  
  71. void insert(treenode *minheap, treenode newNode, int passNum) {
  72.         treenode temp;
  73.         int parent;
  74.         parent = (passNum - 1)/2;
  75.  
  76.         //node you are inserting is bigger than left child, swap them. go again with the new move
  77.         if ((parent >= 0) && (minheap[parent].occurences > newNode.occurences)) {
  78.                 temp = newNode;
  79.                 minheap[passNum].letter = minheap[parent].letter;
  80.                 minheap[passNum].occurences = minheap[parent].occurences;
  81.                 minheap[passNum].left = minheap[parent].left;
  82.                 minheap[passNum].right = minheap[parent].right;
  83.  
  84.                 minheap[parent].letter = temp.letter;
  85.                 minheap[parent].occurences = temp.occurences;
  86.                 minheap[parent].left = temp.left;
  87.                 minheap[parent].right = temp.right;
  88.  
  89.                 passNum = parent;
  90.                 insert(minheap, minheap[parent], passNum);
  91.         }
  92. }
  93.  
  94. //FIXME: not only does it not accept z, but idk how to print the "code"...
  95. //OR if I'm not supposed to print the code, what AM I supposed to print?
  96. void Preorder(treenode *z, ofstream &preorder) {
  97.         if (z) {
  98.                 preorder << z->letter;
  99.                 cout<<"writing "<<z->letter << " ...occur = " << z->occurences << endl;
  100.                 Preorder(z->left, preorder);
  101.                 Preorder(z->right, preorder);
  102.         }
  103. }
  104.  
  105. //FIXME
  106. void Inorder(treenode *z, ofstream &inorder) {
  107.         if (z) {
  108.                 Inorder(z->left, inorder);
  109.                 cout << "writing " << z->letter << " ...occur = " << z->occurences << endl;
  110.                 inorder << z->letter;
  111.                 Inorder(z->right, inorder);
  112.         }
  113. }
  114.  
  115. //FIXME
  116. void Encode(ofstream &encode) {
  117.  
  118. }
  119.  
  120.  
  121. //You must create a binary heap data structure that uses an array and implements insert and extract-min that run in O(lg N) time.
  122.  
  123. int main(int argc, char *argv[]) {
  124.         //read the text from the file given as a command line argument
  125.         ifstream infile;
  126.         infile.open(argv[1]);
  127.         if (infile.fail()) return 0;
  128.  
  129.         //get each character, store number of occurences
  130.         int asciiTable[128];
  131.         char getChar;
  132.         int numLetters = 0;
  133.         while(infile.get(getChar)) {
  134.                 int ascii = (int) getChar;
  135.                 if (!asciiTable[ascii]) numLetters++;
  136.                 asciiTable[ascii]++;
  137.         }
  138.  
  139.         cout << "num letters = " << numLetters << endl;
  140.         cout << "Table: " << endl;
  141.         for (int i = 0; i < 128; i++) {
  142.                 if (asciiTable[i]) {
  143.                         cout << "i= " << i << "...char = " << (char)i << "...Occur=" << asciiTable[i] << endl;
  144.                 }
  145.         }
  146.         cout << endl;
  147.  
  148.         //build the unsorted array
  149.         int j = 0;
  150.         treenode unsorted[numLetters];
  151.         treenode minheap[numLetters];
  152.         for (int i = 0; i < 128; i++) {
  153.                 if (asciiTable[i]) {
  154.                         unsorted[j].occurences = asciiTable[i];
  155.                         unsorted[j].letter = char(i);
  156.                         j++;
  157.                 }
  158.         }
  159.  
  160.         //insert the unsorted array into a min order heap
  161.         for (int i = 0; i < numLetters; i++) {
  162.                 if (i == 0) {                           //if head is empty
  163.                         minheap[0] = unsorted[0];       //place item in root
  164.                         //cout << "In i==0" << endl;
  165.                 }
  166.                 else {
  167.                         minheap[i] = unsorted[i];
  168.                         minheap[i].left = NULL;
  169.                         minheap[i].right = NULL;
  170.                         insert(minheap, unsorted[i], i);
  171.                 }
  172.         }
  173.  
  174.         //delete this later...checks the order after min heap
  175.         for (int i = 0; i< numLetters; i++) {
  176.                 cout << "Char = " << minheap[i].letter << "...num = " << minheap[i].occurences << endl;
  177.         }
  178.  
  179.         //FIXME: build the Huffman code tree using the heap. as you create new internal nodes, give them a unique character label, using values >128
  180.         //call extract-min twice...make the two lowest the new nodes
  181.         //make a new node..adding those two old nodes together
  182.         //add the new node to the list...repeat
  183.         int passNum = numLetters -1;
  184.         //FIXME: change 97 to 128
  185.         int a = 97;
  186.         treenode *root;
  187.         while (passNum > 0) {
  188.                 treenode *z = new treenode;
  189.                 treenode *tleft = extractMin(minheap,passNum);
  190.                 cout << "t.left.occur = " << tleft->occurences << " ...char =" << tleft->letter << endl;
  191.                 z->left = tleft;
  192.  
  193.                 treenode *tright = extractMin(minheap, passNum);
  194.                 cout << "t.right.occur = " << tright->occurences << " ...char =" << tright->letter << endl << endl;
  195.                 z->right = tright;
  196.  
  197.                 z->occurences = z->left->occurences + z->right->occurences;
  198.                 z->letter = char(a++);
  199.  
  200.                 passNum += 1;
  201.                 minheap[passNum] = *z;
  202.                 insert(minheap, minheap[passNum], passNum);
  203.  
  204.                 cout << "passNum after insert = " << passNum << endl;
  205.                 for (int k = 0; k< passNum; k++) {
  206.                         cout << "Char = " << minheap[k].letter << "...num = " << minheap[k].occurences << endl;
  207.                 }
  208.  
  209.  
  210.                 cout << endl;
  211.                 cout << "z->left->occurences = " << z->left->occurences << "....z->left->letter = " << z->left->letter << endl; cout << "z->right->occurences = " << z->right->occurences << "...z->right->letter = " << z->right->letter << endl << "z->occurences = " << z->occurences << ".........z->leter = " << z->letter << endl << "-------------"<< endl;
  212.                 root = z;
  213.         }
  214.  
  215.         //FIXME: write the pre-order traversal to the file "preorder"
  216.         ofstream myfile;
  217.         myfile.open("preorder");
  218.         cout << "1      " << endl;
  219.         Preorder(root, myfile);
  220.         myfile.close();
  221.         cout << "past preorder" << endl;
  222.  
  223.         //FIXME: write the in-order traversal to the file "inorder"
  224.         ofstream myfile2;
  225.         myfile2.open("inorder");
  226.         cout << "opened inorder" << endl;
  227.         Inorder(root, myfile2);
  228.         myfile2.close();
  229.         cout << "past inorder" << endl;
  230.  
  231.         //FIXME: construct a table containing the encoding for each character, storing the encoding as a string
  232.         string table[numLetters];
  233.  
  234.         //FIXME: encode the original text, writing the econded version to "code.txt". This file should be ASCII '0' and '1' characters
  235.         ofstream myfile3;
  236.         myfile3.open("code.txt");
  237.         Encode(myfile3);
  238.         myfile3.close();
  239.  
  240.         return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement