Skip to content
Permalink
6ca19c3d65
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
103 lines (82 sloc) 2.99 KB
#include "Compress.H"
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
map<char,int> Compress::countLetters(){
std::ifstream inpFile (_fname); //Will read the file
std::string line;
map<char,int> freq = map<char,int>();
if (!inpFile.is_open()) throw(std::string("[Error] Could not open file " + _fname + " for countLetters() \n"));
//This part will count the number of occurences
char c;
while(inpFile.get(c)){
freq[c]++;
}
inpFile.close();
return freq;
}
void Compress::generateTree(){
map<char,int> freq = countLetters();
vector<shared_ptr<Node>> lst = vector<shared_ptr<Node>>(freq.size());
//Add the char and its frequency into a vector
auto mapit = freq.begin();
for (auto it = lst.begin(); it != lst.end();it++,mapit++){
*it = std::make_shared<Node>(Node(mapit->second,mapit->first,NULL,NULL));
}
while(lst.size() > 1){ //Will combine the two smallest Nodes until there is only one node
std::sort(lst.begin(),lst.end(),[](std::shared_ptr<Node> l1, std::shared_ptr<Node> l2)->bool{return l1->value < l2->value;});
if (lst[0]->value < lst[1]->value){
lst[1] = std::make_shared<Node>(Node(lst[0]->value + lst[1]->value,'\0',lst[0],lst[1]));
}
else{
lst[1] = std::make_shared<Node>(Node(lst[0]->value + lst[1]->value,'\0',lst[1],lst[0]));
}
lst.erase(lst.begin());
}
_tree = lst[0];
}
//NEED NUMBER OF BITS FOR BODY
string Compress::generateBody(){
ifstream inpFile(_fname);
if(!inpFile.is_open()) throw("[Error] Could not open file " + _fname + " for generateBody()");
if (!_bitMap.size()) throw("[Error in generateBody()] _bitMap is empty");
string uncompressed = ""; // Will hold binary string representation of compression
char c;
while(inpFile.get(c)){
uncompressed += _bitMap[c];
}
cout <<"UncomPressed binary: " << uncompressed << endl;
inpFile.close();
_counter = uncompressed.size();
// cout << "Uncompressed string: " << uncompressed << endl;
return convertToBits(uncompressed);
}
void Compress::compressFile(string outFile){
ofstream outF(outFile);
if (!outF.is_open()) throw("[Error] Error accessing file " + outFile + " in compressFile\n");
string body = generateBody();
cout << "Size of Body compressed : " << body.length() << endl;
string header = generateHeader();
outF << header + body;
}
string Compress::generateHeader(){
string headerLetters = "";
string tmp = preOrder(_tree,headerLetters);
string comp = convertToBits(tmp);
//# of bits in preorder / # of bits in body / preorder in bit form / letters in the preorder tree
return to_string(tmp.size()) + "/" + to_string(_counter) + "/" + comp + headerLetters;
}
int main(int argc, char *argv[]){
using namespace std;
try{
shared_ptr<Compress> conv = make_shared<Compress>(Compress(argv[1]));
conv->generateTree();
conv->generateBitMap();
conv->printPreorder();
conv->compressFile("random");
}
catch(const string &e){cout << e;}
return 0;
}