Добавил:
morpex_1_
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:лабы мышев / лаба2
.cpp#include <iostream>
#include <fstream>
#include <map>
#include <bitset>
#include <clocale>
#include <string>
#include <list>
#include <vector>
#include <cmath>
using namespace std;
string binarystr;
string coded;
string decoded;
vector<string> binarystrs;
vector<bool> code;
map<string, vector<bool> > table;
class Node
{
public:
string str;
int count;
Node* left; Node* right;
Node() {}
Node(Node* l, Node* r) { left = l; right = r; count = l->count + r->count; }
};
void Print(Node* root, unsigned k = 0)
{
if (root != NULL)
{
Print(root->left, k + 3);
for (unsigned i = 0; i < k; i++) {
cout << " ";
}
if (root->str != "\0")
cout << root->count << " (" << root->str << ")" << endl;
else
cout << root->count << endl;
Print(root->right, k + 3);
}
}
struct MyCompare
{
bool operator() (Node* l, Node* r) const
{
return l->count < r->count;
}
};
void DelenieNaStroki(int LetterSize)
{
if (binarystr.size() % LetterSize != 0)
{
int dif = binarystr.size() % LetterSize;
for (int i = 0; i < LetterSize - dif; i++)
binarystr += '0';
}
string temp;
for (int i = 1; i <= binarystr.size(); i++)
{
if (i % LetterSize == 0) {
temp += binarystr[i - 1];
binarystrs.push_back(temp);
temp = "\0";
continue;
}
temp += binarystr[i - 1];
}
}
void BuildTable(Node* current, Node* root)
{
if (current->left != nullptr) {
code.push_back(0);
BuildTable(current->left, root);
}
if (current->right != nullptr) {
code.push_back(1);
BuildTable(current->right, root);
}
if (current->str != "\0")
table[current->str] = code;
if (current != root) code.pop_back();
}
string Coding(int LetterSize)
{
string temp, code = "\0";
for (int i = 1; i <= binarystr.length(); i++)
{
if (i % LetterSize == 0)
{
temp += binarystr[i - 1];
for (map<string, vector<bool> >::iterator it = table.begin(); it != table.end(); it++)
{
if (temp == it->first)
{
for (int j = 0; j < it->second.size(); j++)
{
if (it->second[j] == 0)
code += "0";
else
code += "1";
}
temp = "\0";
break;
}
}
}
else
temp += binarystr[i - 1];
}
return code;
}
void Decoding(string coded, Node* temp, Node* root, int i = 0)
{
//нужно пробегать строку без последних нулей
if (coded[i] != '\0' || coded[i] == '\0') {
if (temp->str != "\0") {
decoded += temp->str;
temp = root;
}
if (coded[i] == '0') {
Decoding(coded, temp->left, root, ++i);
}
else if (coded[i] == '1') {
Decoding(coded, temp->right, root, ++i);
}
}
}
void WriteInFile()
{
ofstream fout("D:\\Coded.txt");
if (!fout.is_open())
{
cout << "Ошибка"; exit(-1);
}
string temp;
int decnum = 0;
//переводим двоичные строки в числа
for (int i = 1; i <= coded.size(); i++)
{
if (i % 8 == 0)
{
temp += coded[i-1];
for (int j = 0; j < temp.size(); j++)
{
if (temp[j] == '1')
{
decnum += pow(2, 7 - j);
}
}
fout << (char)decnum;
temp = "\0";
decnum = 0;
}
else
temp += coded[i-1];
}
}
void MyShiza(Node* root, string codedwithoutzeros)
{
//убираем лишние нули, загоняем битовую цепочку в строку и по известному алгоритму декодируем. Затем выводим готовое сообщение в Decoded
bitset<8> set;
string codedfromfile;
char ch;
ifstream fin("D:\\Coded.txt");
if (!fin.is_open()) {
cout << "Ошибка";
exit(-1);
}
while (fin.get(ch)) {
set = (int)ch;
codedfromfile += set.to_string();
}
int size = codedfromfile.size();
for (int i = 0; i < size - codedwithoutzeros.size(); i++)
codedfromfile.pop_back();
decoded = "\0";
Decoding(codedfromfile, root, root);
string temp;
ofstream fout("D:\\Decoded.txt");
if (!fout.is_open()) {
exit(-1);
}
for (int i = 1; i <= decoded.size(); i++)
{
if (i % 8 == 0)
{
temp += decoded[i - 1];
int num = 0;
for (int j = 0; j < temp.size(); j++) {
if(temp[j] == '1')
num += pow(2, 7 - j);
}
fout << (char)num;
num = 0;
temp = "\0";
continue;
}
else
temp += decoded[i - 1];
}
fout.close();
}
int main()
{
setlocale(LC_ALL, "rus");
string initialstr;
char ch;
bitset<8> set;
ifstream fin("D:\\File1.txt");
if (!fin.is_open()) {
cout << "Ошибка\n";
exit(-1);
}
fin >> initialstr;
fin.close();
ifstream fin1("D:\\File1.txt");
if (!fin1.is_open()) {
cout << "Ошибка\n";
exit(-1);
}
while (fin1.get(ch)) {
set = (int)ch;
binarystr += set.to_string();
}
cout << "Исходная строка:\n" << initialstr << endl << binarystr;
//надо раздробить двоичную строку на несколько
int LetterSize;
cout << "\n\nВведите размер буквы:\n";
cin >> LetterSize;
DelenieNaStroki(LetterSize);
//for (int i = 0; i < binarystrs.size(); i++)
//cout << endl << binarystrs[i];
map<string, int> mp;
string temp;
for (int i = 0; i < binarystrs.size(); i++) {
temp = binarystrs[i];
mp[temp]++;
}
list<Node*> lst;
Node* p;
map<string, int>::iterator it;
for (it = mp.begin(); it != mp.end(); it++)
{
p = new Node;
p->str = it->first;
p->count = it->second;
lst.push_back(p);
}
while (lst.size() != 1)
{
lst.sort(MyCompare());
Node* left = lst.front();
lst.pop_front();
Node* right = lst.front();
lst.pop_front();
Node* parent = new Node(left, right);
lst.push_back(parent);
}
Node* root = lst.front();
//теперь кодируем
//cout << endl << endl;
Print(root);
BuildTable(root, root);
cout << endl << endl << "Словарь:\n";
for (map<string, vector<bool> >::iterator it = table.begin(); it != table.end(); it++)
{
cout << it->first << "\t";
for (int j = 0; j < it->second.size(); j++)
cout << it->second[j];
cout << endl;
}
coded = Coding(LetterSize);
cout << coded << endl;
//добавим нули
string codedwithourzeros = coded;
int dif = coded.size() % 8;
if (dif != 0)
{
for (int i = 1; i <= 8 - dif; i++)
coded += '0';
}
cout << coded;
Decoding(codedwithourzeros, root, root);
cout << endl << decoded;
WriteInFile();
MyShiza(root, codedwithourzeros);
}