Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <map>
- #include <fstream>
- #include <string>
- #include <iostream>
- #define separator ((char)(1))
- #define endOfCode ((char)(2))
- class Compressor
- {
- public:
- static std::string ConvertBitsToString(std::string &bits)
- {
- std::string word;
- unsigned char symbol = ' ';
- int mask = 0;
- for (auto bit: bits)
- {
- if (!mask)
- {
- word.push_back(symbol);
- mask = 1 << 7;
- symbol |= mask;
- mask >>= 1;
- }
- if (bit == '1')
- {
- symbol = symbol | mask;
- }
- else
- {
- symbol = symbol & (~mask);
- }
- mask >>= 1;
- }
- return word;
- }
- static inline bool IsGoodSymbol(char symbol)
- {
- return
- symbol != '\n' && symbol != '\t' && symbol != ' ' &&
- symbol != ';' && symbol != ':' && symbol != '.' &&
- symbol != ',' && symbol != '"' && symbol != '<' &&
- symbol != '>' && symbol != '?' && symbol != ',' &&
- symbol != '/' && symbol != '\\' && symbol != '-' &&
- symbol != '+' && symbol != '=' && symbol != '*' &&
- symbol != '%' && symbol != '!' && symbol != '#' &&
- symbol != '~' && symbol != '&' && symbol != '{'&&
- symbol != '}' && symbol != '[' && symbol != ']'&&
- symbol != '|' && symbol != '^' && symbol != '\''&&
- symbol != '(' && symbol != ')' && (symbol < '0' ||
- symbol > '9');
- }
- static std::map<std::string, int> CountWords(std::string path)
- {
- std::ifstream file;
- try
- {
- file.open(path);
- }
- catch (const std::exception&)
- {
- throw std::exception("File doesnt exist!");
- }
- std::map<std::string, int> Words;
- std::string curentWord;
- char symbol = 's';
- while (!file.eof())
- {
- while (IsGoodSymbol(symbol) && !file.eof())
- {
- curentWord.push_back(symbol);
- file.get(symbol);
- }
- if (curentWord.length() == 0)
- {
- curentWord.push_back(symbol);
- file.get(symbol);
- }
- Words[curentWord]++;
- curentWord.clear();
- }
- file.close();
- return Words;
- }
- static std::map<std::string, std::string> BulidBinarCode(std::map<std::string, int> words)
- {
- std::map<std::string, std::string> code;
- std::string curentCode("1");
- while (!words.empty())
- {
- std::pair<std::string, int> max;
- for (auto e : words)
- {
- if (e.second > max.second)
- {
- max = e;
- }
- }
- words.erase(max.first);
- code[max.first] = curentCode;
- curentCode += "0";
- }
- return code;
- }
- static std::pair<std::string, int> *FindMax(std::map<std::string, int> &words)
- {
- std::pair<std::string, int> *max = new std::pair<std::string, int>("",0);
- for (auto e : words)
- {
- if (e.second > max->second)
- {
- *max = e;
- }
- }
- return max;
- }
- static std::map<std::string, std::string> BulidSymbolCode(std::map<std::string, int> words)
- {
- std::map<std::string, std::string> code;
- std::string curentCode;
- curentCode.push_back('A');
- char curentSymbol = 'B';
- while (!words.empty())
- {
- auto max = FindMax(words);
- words.erase(max->first);
- code[max->first] = curentCode + curentSymbol;
- curentSymbol++;
- if (curentSymbol == 'Z' + 1)
- {
- curentCode.push_back('A');
- curentSymbol = 'B';
- }
- delete max;
- }
- return code;
- }
- static std::map<std::string, std::string> ReadCode(std::string path)
- {
- static std::map<std::string, std::string>Code;
- std::ifstream file(path);
- char symbol;
- std::string word;
- std::string code;
- while (true)
- {
- file.get(symbol);
- if (symbol == endOfCode)
- {
- break;
- }
- while (symbol != separator)
- {
- word.push_back(symbol);
- file.get(symbol);
- }
- file.get(symbol);
- while (symbol != separator)
- {
- code.push_back(symbol);
- file.get(symbol);
- }
- Code[word] = code;
- word.clear();
- code.clear();
- }
- file.close();
- return Code;
- }
- static void ZipFile(std::string input, std::string output)
- {
- auto words = CountWords(input);
- auto code = BulidSymbolCode(words);
- std::ifstream file(input);
- std::ofstream outputFile(output);
- char symbol;
- std::string curentWord;
- for (auto e : code)
- {
- outputFile << e.second.c_str() << separator << e.first.c_str() << separator;
- }
- outputFile << endOfCode;
- file.get(symbol);
- while (!file.eof())
- {
- while (IsGoodSymbol(symbol) && !file.eof())
- {
- curentWord.push_back(symbol);
- file.get(symbol);
- }
- if (curentWord.length() == 0 && !IsGoodSymbol(symbol))
- {
- curentWord.push_back(symbol);
- file.get(symbol);
- }
- outputFile << code[curentWord].c_str();
- curentWord.clear();
- }
- file.close();
- outputFile.close();
- }
- static void UnZipFile(std::string path, std::string output)
- {
- auto code = ReadCode(path);
- std::ifstream file(path);
- std::ofstream outputFile(output);
- std::string word;
- while (file.peek() != endOfCode)
- {
- file.get();
- }
- file.get();
- char symbol;
- int lastIndex;
- file.get(symbol);
- while (!file.eof())
- {
- word.clear();
- while (symbol == 'A' && !file.eof())
- {
- word.push_back(symbol);
- file.get(symbol);
- }
- word.push_back(symbol);
- file.get(symbol);
- outputFile << code[word];
- }
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement