tachia

Untitled

Jun 20th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.53 KB | None | 0 0
  1. /**********************************************************
  2.  * File: HuffmanEncoding.cpp
  3.  *
  4.  * Implementation of the functions from HuffmanEncoding.h.
  5.  * Most (if not all) of the code that you write for this
  6.  * assignment will go into this file.
  7.  */
  8.  
  9. #include "HuffmanEncoding.h"
  10. #include "pqueue.h"
  11. #include "map.h"
  12. #include "strlib.h"
  13.  
  14. /* Function: getFrequencyTable
  15.  * Usage: Map<ext_char, int> freq = getFrequencyTable(file);
  16.  * --------------------------------------------------------
  17.  * Given an input stream containing text, calculates the
  18.  * frequencies of each character within that text and stores
  19.  * the result as a Map from ext_chars to the number of times
  20.  * that the character appears.
  21.  *
  22.  * This function will also set the frequency of the PSEUDO_EOF
  23.  * character to be 1, which ensures that any future encoding
  24.  * tree built from these frequencies will have an encoding for
  25.  * the PSEUDO_EOF character.
  26.  */
  27. Map<ext_char, int> getFrequencyTable(istream& file) {
  28.     char ch;
  29.     Map<ext_char, int> frequence;
  30.     while(file.get(ch)){
  31.         if(ch!=NOT_A_CHAR){
  32.             if(frequence.containsKey(ch)){
  33.                 int a = frequence.get(ch);
  34.                 a+=1;
  35.                 frequence.put(ch, a);
  36.             } else {
  37.                 frequence.put(ch, 1);
  38.             }
  39.         }
  40.     }
  41.     frequence.put(PSEUDO_EOF, 1);
  42.     return frequence;  
  43. }
  44.  
  45. /* Function: buildEncodingTree
  46.  * Usage: Node* tree = buildEncodingTree(frequency);
  47.  * --------------------------------------------------------
  48.  * Given a map from extended characters to frequencies,
  49.  * constructs a Huffman encoding tree from those frequencies
  50.  * and returns a pointer to the root.
  51.  *
  52.  * This function can assume that there is always at least one
  53.  * entry in the map, since the PSEUDO_EOF character will always
  54.  * be present.
  55.  */
  56. Node* buildEncodingTree(Map<ext_char, int>& frequencies) {
  57.     // TODO: Implement this!
  58.     PriorityQueue<Node*> nodesQueue;
  59.     foreach(ext_char ch in frequencies){
  60.         if(ch!=NOT_A_CHAR){
  61.             Node* node = new Node;
  62.             node->character=ch;
  63.             node->one = node->zero=NULL;
  64.             node->weight = frequencies.get(ch);
  65.             double a = frequencies.get(ch);
  66.             nodesQueue.enqueue(node, a);
  67.         }
  68.     }
  69.     while(!nodesQueue.isEmpty()){
  70.         if(nodesQueue.size()>1){
  71.             Node* first = nodesQueue.dequeue();
  72.             Node* second = nodesQueue.dequeue();
  73.             Node* root = new Node;
  74.             root->weight = first->weight + second ->weight;
  75.             root->zero=second;
  76.             root->one=first;
  77.             root->character=NOT_A_CHAR;
  78.             double a = root->weight;
  79.             nodesQueue.enqueue(root, a);
  80.         }
  81.         if(nodesQueue.size()==1){
  82.             return nodesQueue.dequeue();
  83.         }
  84.     }
  85.     return NULL;
  86. }
  87.  
  88. /* Function: freeTree
  89.  * Usage: freeTree(encodingTree);
  90.  * --------------------------------------------------------
  91.  * Deallocates all memory allocated for a given encoding
  92.  * tree.
  93.  */
  94. void freeTree(Node* root) {
  95.     if(root==NULL){
  96.         return;
  97.     } else {
  98.         freeTree(root->zero);
  99.         freeTree(root->one);
  100.         delete root;
  101.     }
  102.  
  103. }
  104.  
  105. /* Function: encodeFile
  106.  * Usage: encodeFile(source, encodingTree, output);
  107.  * --------------------------------------------------------
  108.  * Encodes the given file using the encoding specified by the
  109.  * given encoding tree, then writes the result one bit at a
  110.  * time to the specified output file.
  111.  *
  112.  * This function can assume the following:
  113.  *
  114.  *   - The encoding tree was constructed from the given file,
  115.  *     so every character appears somewhere in the encoding
  116.  *     tree.
  117.  *
  118.  *   - The output file already has the encoding table written
  119.  *     to it, and the file cursor is at the end of the file.
  120.  *     This means that you should just start writing the bits
  121.  *     without seeking the file anywhere.
  122.  */
  123. void allCode(Node* encodingTree, Map<ext_char, string> &codesMap, string & path){
  124.     Node * first;
  125.     Node * zeroo;
  126.     if(encodingTree!=NULL){
  127.         first=encodingTree->one;
  128.         zeroo=encodingTree->zero;
  129.         if( encodingTree->character!=NOT_A_CHAR){
  130.             codesMap.put(encodingTree->character,path);
  131.             path="";
  132.         }else if(encodingTree->character==PSEUDO_EOF){
  133.             codesMap.put(encodingTree->character,path);
  134.             path="";
  135.        
  136.         }
  137.     }else{
  138.         return;
  139.     }
  140.     if(first!=NULL){
  141.     allCode(first,codesMap,path+'1');
  142.     }
  143.     if(zeroo!=NULL){
  144.     allCode(zeroo,codesMap,path+'0');
  145.     }
  146. }
  147.  
  148.  
  149. void encodeFile(istream& infile, Node* encodingTree, obstream& outfile) {
  150.     Map<ext_char, string> codesMap;
  151.     string path="";
  152.     allCode(encodingTree, codesMap, path);
  153.     char ch;
  154.     while(infile.get(ch)){
  155.         string code = codesMap.get(ch);
  156.         for(int i=0; i<code.length(); i++){
  157.             char bit = code[i];
  158.             int a = bit-'0';
  159.             outfile.writeBit(a);
  160.         }
  161.     }
  162.     string code=codesMap.get(PSEUDO_EOF);
  163.     for(int i=0; i<code.length(); i++){
  164.             char bit = code[i];
  165.             int a = bit-'0';
  166.             outfile.writeBit(a);
  167.         }
  168.    
  169. }
  170.  
  171. /* Function: decodeFile
  172.  * Usage: decodeFile(encodedFile, encodingTree, resultFile);
  173.  * --------------------------------------------------------
  174.  * Decodes a file that has previously been encoded using the
  175.  * encodeFile function.  You can assume the following:
  176.  *
  177.  *   - The encoding table has already been read from the input
  178.  *     file, and the encoding tree parameter was constructed from
  179.  *     this encoding table.
  180.  *
  181.  *   - The output file is open and ready for writing.
  182.  */
  183. void decodeFile(ibstream& infile, Node* encodingTree, ostream& file) {
  184.     // TODO: Implement this!
  185. }
  186.  
  187. /* Function: writeFileHeader
  188.  * Usage: writeFileHeader(output, frequencies);
  189.  * --------------------------------------------------------
  190.  * Writes a table to the front of the specified output file
  191.  * that contains information about the frequencies of all of
  192.  * the letters in the input text.  This information can then
  193.  * be used to decompress input files once they've been
  194.  * compressed.
  195.  *
  196.  * This function is provided for you.  You are free to modify
  197.  * it if you see fit, but if you do you must also update the
  198.  * readFileHeader function defined below this one so that it
  199.  * can properly read the data back.
  200.  */
  201. void writeFileHeader(obstream& outfile, Map<ext_char, int>& frequencies) {
  202.     /* The format we will use is the following:
  203.      *
  204.      * First number: Total number of characters whose frequency is being
  205.      *               encoded.
  206.      * An appropriate number of pairs of the form [char][frequency][space],
  207.      * encoding the number of occurrences.
  208.      *
  209.      * No information about PSEUDO_EOF is written, since the frequency is
  210.      * always 1.
  211.      */
  212.      
  213.     /* Verify that we have PSEUDO_EOF somewhere in this mapping. */
  214.     if (!frequencies.containsKey(PSEUDO_EOF)) {
  215.         error("No PSEUDO_EOF defined.");
  216.     }
  217.    
  218.     /* Write how many encodings we're going to have.  Note the space after
  219.      * this number to ensure that we can read it back correctly.
  220.      */
  221.     outfile << frequencies.size() - 1 << ' ';
  222.    
  223.     /* Now, write the letter/frequency pairs. */
  224.     foreach (ext_char ch in frequencies) {
  225.         /* Skip PSEUDO_EOF if we see it. */
  226.         if (ch == PSEUDO_EOF) continue;
  227.        
  228.         /* Write out the letter and its frequency. */
  229.         outfile << char(ch) << frequencies[ch] << ' ';
  230.     }
  231. }
  232.  
  233. /* Function: readFileHeader
  234.  * Usage: Map<ext_char, int> freq = writeFileHeader(input);
  235.  * --------------------------------------------------------
  236.  * Reads a table to the front of the specified input file
  237.  * that contains information about the frequencies of all of
  238.  * the letters in the input text.  This information can then
  239.  * be used to reconstruct the encoding tree for that file.
  240.  *
  241.  * This function is provided for you.  You are free to modify
  242.  * it if you see fit, but if you do you must also update the
  243.  * writeFileHeader function defined before this one so that it
  244.  * can properly write the data.
  245.  */
  246. Map<ext_char, int> readFileHeader(ibstream& infile) {
  247.     /* This function inverts the mapping we wrote out in the
  248.      * writeFileHeader function before.  If you make any
  249.      * changes to that function, be sure to change this one
  250.      * too!
  251.      */
  252.     Map<ext_char, int> result;
  253.    
  254.     /* Read how many values we're going to read in. */
  255.     int numValues;
  256.     infile >> numValues;
  257.    
  258.     /* Skip trailing whitespace. */
  259.     infile.get();
  260.    
  261.     /* Read those values in. */
  262.     for (int i = 0; i < numValues; i++) {
  263.         /* Get the character we're going to read. */
  264.         ext_char ch = infile.get();
  265.        
  266.         /* Get the frequency. */
  267.         int frequency;
  268.         infile >> frequency;
  269.        
  270.         /* Skip the space character. */
  271.         infile.get();
  272.        
  273.         /* Add this to the encoding table. */
  274.         result[ch] = frequency;
  275.     }
  276.    
  277.     /* Add in 1 for PSEUDO_EOF. */
  278.     result[PSEUDO_EOF] = 1;
  279.     return result;
  280. }
  281.  
  282. /* Function: compress
  283.  * Usage: compress(infile, outfile);
  284.  * --------------------------------------------------------
  285.  * Main entry point for the Huffman compressor.  Compresses
  286.  * the file whose contents are specified by the input
  287.  * ibstream, then writes the result to outfile.  Your final
  288.  * task in this assignment will be to combine all of the
  289.  * previous functions together to implement this function,
  290.  * which should not require much logic of its own and should
  291.  * primarily be glue code.
  292.  */
  293. void compress(ibstream& infile, obstream& outfile) {
  294.  
  295.  
  296. }
  297.  
  298. /* Function: decompress
  299.  * Usage: decompress(infile, outfile);
  300.  * --------------------------------------------------------
  301.  * Main entry point for the Huffman decompressor.
  302.  * Decompresses the file whose contents are specified by the
  303.  * input ibstream, then writes the decompressed version of
  304.  * the file to the stream specified by outfile.  Your final
  305.  * task in this assignment will be to combine all of the
  306.  * previous functions together to implement this function,
  307.  * which should not require much logic of its own and should
  308.  * primarily be glue code.
  309.  */
  310. void decompress(ibstream& infile, ostream& outfile) {
  311.    
  312. }
Advertisement
Add Comment
Please, Sign In to add comment