Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабы мышев / лаба2

.cpp
Скачиваний:
2
Добавлен:
07.04.2023
Размер:
6.65 Кб
Скачать
#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);
}
Соседние файлы в папке лабы мышев