IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 简单哈夫曼解压缩 c语言 -> 正文阅读

[C++知识库]简单哈夫曼解压缩 c语言

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef struct tmp_node
{
	unsigned char uch;
	unsigned int weight;
}tmpNode;

typedef struct huf_node
{
	unsigned char uch;
	unsigned int weight;
	int parent, lchild, rchild;
	char* code;
}hufNode, *hufPtr;

void select(hufPtr huf_tree, int n, int* s1, int* s2)
{
	int i = 0;
	unsigned long min = ULONG_MAX;
	for (; i < n; ++i)
	{
		if ( !huf_tree[i].parent && huf_tree[i].weight < min)
		{
			min = huf_tree[i].weight;
			*s1 = i;
		}
	}

	huf_tree[*s1].parent = 1;
	min = ULONG_MAX;
	for (i = 0; i < n; ++i)
	{
		if (!huf_tree[i].parent && huf_tree[i].weight < min)
		{
			min = huf_tree[i].weight;
			*s2 = i;
		}
	}
}

void create_huf_tree(hufPtr huf_tree, int char_kinds, int node_num)
{
	int s1, s2;
	int i = char_kinds;
	for (; i < node_num; ++i)
	{
		select(huf_tree, i, &s1, &s2);
		huf_tree[s1].parent = huf_tree[s2].parent = i;
		huf_tree[i].lchild = s1;
		huf_tree[i].rchild = s2;
		huf_tree[i].weight = huf_tree[s1].weight + huf_tree[s2].weight;
	}
}

void huf_code(hufPtr huf_tree, int char_kinds)
{
	int cur, next;
	int i;
	char code_tmp[256] = { 0 };
	int index;
	for (i = 0; i < char_kinds; i++)
	{
		code_tmp[255] = '\0';
		index = 255;
		for (cur = i, next = huf_tree[cur].parent; next != 0; cur = next, next = huf_tree[next].parent)
		{
			if (cur == huf_tree[next].lchild)
			{
				code_tmp[--index] = '0';
			}
			else
			{
				code_tmp[--index] = '1';
			}

		}
		
		huf_tree[i].code = (char*)malloc( (256 - index) * sizeof(char));
		assert(huf_tree[i].code != NULL);
		strcpy(huf_tree[i].code, code_tmp + index);
	}
}

void compress(const char* infile, const char* outfile)
{
	tmpNode* tmp_node = (tmpNode*)malloc(sizeof(tmpNode) * 256);
	assert(tmp_node != NULL);
	for (int i = 0; i < 256; ++i)
	{
		tmp_node[i].uch = (unsigned char)i;
		tmp_node[i].weight = 0;
	}

	FILE* inf = fopen(infile, "rb");
	assert(inf != NULL);

	unsigned char char_tmp;
	unsigned int file_len = 0;
	while (!feof(inf))
	{
		fread((char*)&char_tmp, sizeof(unsigned char), 1, inf);
		++tmp_node[char_tmp].weight;
		++file_len;
	}

	fclose(inf);

	tmpNode swap_node;
	for (int i = 0; i < 255; ++i)
	{
		for (int j = i + 1; j < 256; ++j)
		{
			if (tmp_node[i].weight < tmp_node[j].weight)
			{
				swap_node = tmp_node[i];
				tmp_node[i] = tmp_node[j];
				tmp_node[j] = swap_node;
			}
		}
	}

	int i = 0;
	for (; i < 256; ++i)
	{
		if (!tmp_node[i].weight)
		{
			break;
		}
	}

	int char_kinds = i;

	if (char_kinds == 1)
	{
		FILE* outf = fopen(outfile, "wb");
		assert(outf != NULL);

		fwrite((char*)&char_kinds, sizeof(char_kinds), 1, outf);
		fwrite((char*)&file_len, sizeof(file_len), 1, outf);

		fwrite((char*)&tmp_node[0].uch, sizeof(unsigned char), 1, outf);
		free(tmp_node);
		fclose(outf);
	}
	else
	{
		int node_num = char_kinds * 2 - 1;
		hufPtr huf_tree = (hufPtr)malloc(sizeof(hufNode) * node_num);
		assert(huf_tree != NULL);

		int i;
		for (i = 0; i < char_kinds; ++i)
		{
			huf_tree[i].uch = tmp_node[i].uch;
			huf_tree[i].weight = tmp_node[i].weight;
			huf_tree[i].parent = 0;
		}
		free(tmp_node);

		for (; i < node_num; ++i)
		{
			huf_tree[i].parent = 0;
			huf_tree[i].weight = 0;
		}

		create_huf_tree(huf_tree, char_kinds, node_num);

		huf_code(huf_tree, char_kinds);

		FILE* outf = fopen(outfile, "wb");
		assert(outf != NULL);

		fwrite((char*)&char_kinds, sizeof(char_kinds), 1, outf);
		for (i = 0; i < char_kinds; ++i)
		{
			fwrite((char*)&huf_tree[i].uch, sizeof(unsigned char), 1, outf);
			fwrite((char*)&huf_tree[i].weight, sizeof(unsigned int), 1, outf);
		}

		fwrite((char*)&file_len, sizeof(file_len), 1, outf);

		inf = fopen(infile, "rb");
		assert(inf != NULL);

		char code_buf[256] = { 0 };
		while (!feof(inf))
		{
			fread((char*)&char_tmp, sizeof(char_tmp), 1, inf);
			for (i = 0; i < char_kinds; ++i)
			{
				if (huf_tree[i].uch == char_tmp)
				{
					strcat(code_buf, huf_tree[i].code);
					//break;
				}
			}

			while (strlen(code_buf) >= 8)
			{
				char_tmp = '\0';
				for (i = 0; i < 8; ++i)
				{
					char_tmp <<= 1;
					if (code_buf[i] == '1')
					{
						char_tmp |= 1;
					}
				}

				fwrite((char*)&char_tmp, sizeof(char_tmp), 1, outf);
				strcpy(code_buf, code_buf + 8);
			}
		}

		int code_len = strlen(code_buf);
		if (code_len > 0)
		{
			char_tmp = '\0';
			for (i = 0; i < code_len; ++i)
			{
				char_tmp <<= 1;
				if (code_buf[i] == '1')
				{
					char_tmp |= 1;
				}
			}

			char_tmp <<= (8 - code_len);
			fwrite((char*)&char_tmp, sizeof(char_tmp), 1, outf);
		}

		fclose(inf);
		fclose(outf);

		for (i = 0; i < char_kinds; ++i)
		{
			free(huf_tree[i].code);
		}
		free(huf_tree);
	}
}

void extract(const char* infile, const char* outfile)
{
	FILE* inf = fopen(infile, "rb");
	assert(inf != NULL);

	int char_kinds;
	fread((char*)&char_kinds, sizeof(char_kinds), 1, inf);
	unsigned int file_len;
	unsigned char char_tmp;
	if (char_kinds == 1)
	{
		fread((char*)& file_len, sizeof(file_len), 1, inf);
		fread((char*)&char_tmp, sizeof(char_tmp), 1, inf);

		FILE* outf = fopen(outfile, "wb");
		assert(outf != NULL);

		fwrite((char*)&char_tmp, sizeof(char_tmp), file_len, outf);
		fclose(outf);
		fclose(inf);
		return;
	}
	else
	{
		int node_num = char_kinds * 2 - 1;

		hufPtr huf_tree = (hufPtr)malloc(sizeof(hufNode) * node_num);
		assert(huf_tree != NULL);

		int i;
		for (i = 0; i < char_kinds; ++i)
		{
			fread((char*)&huf_tree[i].uch, sizeof(unsigned char), 1, inf);
			fread((char*)&huf_tree[i].weight, sizeof(unsigned int), 1, inf);
			huf_tree[i].parent = 0;
		}

		for (; i < node_num; ++i)
		{
			huf_tree[i].parent = 0;
			huf_tree[i].weight = 0;
		}

		create_huf_tree(huf_tree, char_kinds, node_num);

		fread((char*)&file_len, sizeof(file_len), 1, inf);
		unsigned int write_len = 0;
		int root = node_num - 1;

		FILE* outf = fopen(outfile, "wb");
		assert(outf != NULL);

		while (1)
		{
			fread((char*)&char_tmp, sizeof(char_tmp), 1, inf);
			
			for (int i = 0; i < 8; ++i)
			{
				if (char_tmp & 128)
				{
					root = huf_tree[root].rchild;
				}
				else
				{
					root = huf_tree[root].lchild;
				}

				if (root < char_kinds)
				{
					fwrite((char*)&huf_tree[root].uch, sizeof(unsigned char), 1, outf);
					root = node_num - 1;
					if (++write_len == file_len)
					{
						break;
					}
				}

				char_tmp <<= 1;
			}

			if (write_len == file_len)
			{
				break;
			}
		}

		fclose(inf);
		fclose(outf);
		free(huf_tree);
	}
	

}

int main(void)
{
	//compress("E://test.png", "E://test.png.hum");
	//extract("E://test.png.hum", "E://testout.png");

	system("pause");
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:33:09  更:2022-03-13 21:34:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:23:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码