// this will requrire one to change the the source directory in the build system #include "algorithms/CPlusPlus/Trees/huffmanCode/huffman.h" #include #include #include #include #include #include #include #include #include #include #include // NOLINT (build/c++11) using namespace std; map frequency; class Node{ public: Node * parent; Node * left; Node * right; char key; int freq; string name; Node(Node * p, Node * l, Node * r, int k, int f) { parent = p; left = l; right = r; key = k; freq = f; } }; void postOrder(Node * root) { if(root->left != nullptr) postOrder(root->left); //cout << root->key << " "; if(root->right != nullptr) postOrder(root->right); if(root->left == nullptr && root->right == nullptr) cout << root->key << " "; } bool cmp(pair& a, pair& b) { return a.second < b.second; } bool compare(Node * a, Node * b) { return a->freq < b->freq; } // Function to sort the map according // to value in a (key-value) pairs vector > sortChars(map& M) { vector > result; for (auto& it : M) { result.push_back(it); } sort(result.begin(), result.end(), cmp); return result; } void updateMap(string textLine) { for(char c : textLine) { frequency[c] +=1; } } vector > getAlphabet(string alphabetSource) { string text; ifstream MyReadFile(alphabetSource); while (getline (MyReadFile, text)) { //frequency['\n'] +=1; updateMap(text); } MyReadFile.close(); vector > results = sortChars(frequency); return results; } Node * getBinary(Node * root, char key, string & binaryCode) { if(root->key==key) return root; else { if(root->left->name.find(key) != string::npos) { //cout << "0"; binaryCode += "0"; return getBinary(root->left, key, binaryCode); } else { //cout << "1"; binaryCode += "1"; return getBinary(root->right, key, binaryCode); } } } string extract(Node * root, string text) { Node * head = root; string result = ""; for(int i=0; ileft; else head = head->right; if(head->left== nullptr && head->right== nullptr) { result.push_back(head->key); head = root; } } return result; } string code(Node * root, string text) { string result = ""; for(int i=0; i> results = getAlphabet(alphabetSourceFilePath); vector nodes; for(auto result : results) { Node * node = new Node(nullptr, nullptr, nullptr, result.first, result.second); node->name = node->key; nodes.push_back(node); } while(nodes.size()>1) { Node * right = nodes[0]; Node * left = nodes[1]; nodes.erase(nodes.begin()); nodes.erase(nodes.begin()); Node * parent = new Node(nullptr, left, right, '\0', left->freq+right->freq); parent->name += left->name + right->name; nodes.push_back(parent); sort(nodes.begin(), nodes.end(), compare); } return nodes[0]; } void writeCodedText(string modifiedSourceFilePath, string textCodeFilePath, Node * root) { string sourceFileLine; ifstream sourceFile(modifiedSourceFilePath); ofstream distenationFile(textCodeFilePath); while (getline (sourceFile, sourceFileLine)) { // Output the text from the file string textLine = sourceFileLine ; // not adding "\n" leaves only white spaces and results in one string string codedText = code(root, textLine); distenationFile << codedText; } sourceFile.close(); distenationFile.close(); } void extractCodedText(string textCodeFilePath, string decodedFilePath, Node * root) { string textCodeFileLine; ifstream textCodeFile(textCodeFilePath); ofstream decodedFile(decodedFilePath); while (getline (textCodeFile, textCodeFileLine)) { string decodedText = extract(root, textCodeFileLine); decodedFile << decodedText; // this i think mostly appends no new lines } textCodeFile.close(); decodedFile.close(); } int codeBinaryFromText(string textCodeFilePath, string binaryResultFilePath) { string sourceTextCodedFileLine; ifstream sourceTextCodedFile(textCodeFilePath); int linesNum = 0; while (getline(sourceTextCodedFile, sourceTextCodedFileLine)) { linesNum = codedBinay(sourceTextCodedFileLine, binaryResultFilePath); } sourceTextCodedFile.close(); return linesNum; } void decompressBinaryFile(string binarySourceFilePath, string textDistnationFilePath,int linesNum, Node * alphabetRoot) { ifstream binaryResultFile(binarySourceFilePath, ios::out | ios::binary); ofstream decodedbinaryFile(textDistnationFilePath); int codedNumber; string allText = ""; for(int i=0; i(codedNumber).to_string(); allText += str; } string decodedText = extract(alphabetRoot, allText); decodedbinaryFile << decodedText; // this i think mostly appends no new lines binaryResultFile.close(); decodedbinaryFile.close(); } int compresstoBinaryFile(string modifiedSourceFilePath, Node * alphabetRoot) { string textCodeFilePath = "results/textCoded.txt"; string decodedTextFilePath = "results/decodedText.txt"; string binaryResultFilePath = "results/BinaryCoded.dat"; writeCodedText(modifiedSourceFilePath, textCodeFilePath, alphabetRoot); extractCodedText(textCodeFilePath, decodedTextFilePath, alphabetRoot); int linesNum = codeBinaryFromText(textCodeFilePath, binaryResultFilePath); return linesNum; }