Huffman哈夫曼编码译码器(文件输入输出流)C语言(C++)

C语言(其中用到了c++)

哈夫曼编码译码器,做课程设计的,许多网上的资料都不能直接使用,以下是经过修改后能成功运行的,其中huffman.txt文件放在项目目录,需要的可以自己改代码

下面上代码:

(现在scanf,getch都不能直接使用,需要在上面加上#define _CRT_SECURE_NO_WARNINGS或者是使用scanf_s,_getch,诸如此类)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <string>
#include <math.h>

using namespace std;

#define  n 100
#define m 2*n-1

typedef struct
{
	char ch;
	char bits[9];
	int len;
}CodeNode;

typedef CodeNode HuffmanCode[n + 1];
typedef struct
{
	int weight;
	int lchild, rchild, parent;
}HTNode;
typedef HTNode HuffmanTree[m + 1];
int num;

void select(HuffmanTree HT, int k, int&s1, int&s2)// 两节点选最小2个
{
	int i, j;
	int minl = 32767;
	for (i = 1; i <= k; i++)
	{
		if (HT[i].weight<minl&&HT[i].parent == 0)
		{
			j = i;
			minl = HT[i].weight;
		}
	}
	s1 = j;
	minl = 32767;
	for (i = 1; i <= k; i++)
	{
		if (HT[i].weight<minl&&HT[i].parent == 0 && i != s1)
		{
			j = i;
			minl = HT[i].weight;
		}
	}
	s2 = j;
}

int countAsc(char *s, int cnt[], char str[])
{
	char *p;
	int i, j, k = 0;
	int temp[257];
	for (i = 0; i<257; i++)
	{
		temp[i] = 0;
	}
	for (p = s; *p != '\0'; p++)
	{
		temp[*p]++;
	}
	for (i = 0, j = 0; i <= 256; i++)
	{
		if (temp[i] != 0)
		{
			j++;
			str[j] = i;
			cnt[j] = temp[i];
		}
	}
	num = j;
	return j;
}

void createHuffmanTree(HuffmanTree& HT, HuffmanCode&HC, int cnt[], char str[])
{
	int i, s1, s2;
	for (i = 1; i <= 2 * num - 1; i++)
	{
		HT[i].lchild = 0;
		HT[i].rchild = 0;
		HT[i].parent = 0;
		HT[i].weight = 0;
	}
	for (i = 1; i <= num; i++)
	{
		HT[i].weight = cnt[i];
	}
	for (i = num + 1; i <= 2 * num - 1; i++)
	{
		select(HT, i - 1, s1, s2);
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
	for (i = 1; i <= num; i++)
	{
		HC[i].ch = str[i];
	}
}


void huffmanencoding(HuffmanTree &HT, HuffmanCode &HC)
{
	int c, p, i;
	char cd[n];
	int start;
	cd[num] = '\0';
	for (i = 1; i <= num; i++)
	{
		start = num;
		c = i;
		while ((p = HT[c].parent)>0)
		{
			start--;
			cd[start] = (HT[p].lchild == c) ? '0' : '1';
			c = p;
		}
		strcpy(HC[i].bits, &cd[start]);
		HC[i].len = num - start;
	}
}

void decode(HuffmanCode &HC, /*char receive[],*/ char s[])
{
	FILE *fp;
	fopen_s(&fp, "huffman.txt", "r");
	if (fp==NULL)
	{
		return;
	}
	char ch;
	int num = 0;
	while (ch = getc(fp) != EOF)
	{
		num++;
	}
	cout << "已成功读取文件,其文本长度为:" << num << endl;
	fclose(fp);

	ifstream in("huffman.txt");
	string line;
	char result[200];
	int z = 0;
	if (in)
	{
		while (!in.eof())
		{
			in >> ch;
			result[z] = ch;
			z++;
		}
	}
	else
	{
		cout << "没有此文件或读取错误!" << endl;
	}
	result[num] = '\0';

	cout << result << endl;
	in.close();
	
	char str[268];
	char cd[9];
	int i, j, k = 0, p = 0, flag;
	while (result[p] != '\0')
	{
		flag = 0;
		for (i = 0; i<num && flag == 0 && result[p] != '/0'; i++)
		{
			cd[i] = ' ';
			cd[i + 1] = '\0';
			cd[i] = result[p++];
			for (j = 1; j <= num; j++)
			{
				if (strcmp(HC[j].bits, cd) == 0)
				{
					str[k] = HC[j].ch;
					k++;
					flag = 1;
					break;
				}
			}
		}
	}
	str[k] = '\0';
	strcpy(s, str);	
}


void coding(HuffmanCode &HC, char  str[], char get[])
{
	int i, j = 0;
	while (str[j] != '\0')
	{
		for (i = 1; i <= num; i++)
		{
			if (HC[i].ch == str[j])
			{
				strcat(get, HC[i].bits);
				break;
			}
		}
		j++;
	}
	strcat(get, "\0");
	int len =sizeof(get)/sizeof(get[0]);
	//cout << "长度:"<<len << endl;
	FILE *fp;
	fopen_s(&fp, "huffman.txt", "w");
	fputs(get, fp);
	fclose(fp);
}

void main()
{
	char str[257];
	char st[10000], sresult[10000];
	int cn[257];
	HuffmanTree HT;
	HuffmanCode HC;
	printf("please输入要编码的字符串:\n");
	scanf("%s", &st);
	num = countAsc(st, cn, str);
	str[num + 1] = '\0';
	createHuffmanTree(HT, HC, cn, str);
	huffmanencoding(HT, HC);
	printf("共有%d种符号\n", num);
	for (int i = 1; i <= num; i++)
	{
		printf("字符%c次数为%d,编码为%s\n", HC[i].ch, cn[i], HC[i].bits);
	}
	char get[10000];
	get[0] = '\0';
	coding(HC, st, get);
	printf("上述字符串的霍夫曼吗为%s\n", get);
	printf("编码后结果已存储在huffman.txt中...\n");
	decode(HC, sresult);
	printf("译码得:%s\n", sresult);
}


  • 5
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值