[数据压缩]_实验② lzw编解码

本文详细介绍了LZW编码的原理和实现,包括编码过程、动态词典管理和解码策略。通过C语言编程实现LZW编码器,分析编码效果,并针对不同文件格式的压缩效率进行了比较。实验结果显示,LZW编码对重复率高的文件压缩效果显著,但对重复率低的文件压缩效果不佳。
摘要由CSDN通过智能技术生成

一. 实验名称

LZW编解码算法实现与分析

二. 实验目的

掌握词典编码的基本原理,用c语言编程实现LZW编码器,并分析编码原理。

三. 实验要求
  1. 首先调试LZW的编码程序,以一个文本文件作为输入,得到输出的LZW编码文件。

  2. 以实验步骤一得到的编码文件作为输入,编写LZW的解码程序。在写解码程序时需要对关键语句加上注释,并说明进行何操作。在实验报告中重点说明当前码字在词典中不存在时应如何处理并解释原因。

  3. 选择至少十种不同格式类型的文件,使用LZW编码器进行压缩得到输出的压缩比特流文件。对各种不同格式的文件进行压缩效率的分析。

四. 实验原理
1.主函数

在这里插入图片描述

代码
int main(int argc, char** argv) {
	FILE* fp;
	BITFILE* bf;

	if (argc<4) {
		fprintf(stdout, "usage: \n%s <o> <ifile> <ofile>\n", argv[0]);
		fprintf(stdout, "\t<o>: E or D reffers encode or decode\n");
		fprintf(stdout, "\t<ifile>: input file name\n");
		fprintf(stdout, "\t<ofile>: output file name\n");
		return -1;
	}

	if ('E' == argv[1][0]) { 
		//打开输入文件
		fp = fopen(argv[2], "rb");
		//创建输出文件
		bf = OpenBitFileOutput(argv[3]);
		if (NULL != fp && NULL != bf) {
			LZWEncode(fp, bf);
			PrintDictionary();
			fclose(fp);
			CloseBitFileOutput(bf);
			fprintf(stdout, "encoding done\n");
		}
	}
	else if ('D' == argv[1][0]) {	
		//创建输出文件
		bf = OpenBitFileInput(argv[2]);
		//打开解压文件
		fp = fopen(argv[3], "wb");
		if (NULL != fp && NULL != bf) {
			LZWDecode(bf, fp);
			PrintDictionary();
			fclose(fp);
			CloseBitFileInput(bf);
			fprintf(stdout, "decoding done\n");
		}
	}
	else {	
		fprintf(stderr, "not supported operation\n");
	}
	return 0;
}
2.编码原理和实现算法
原理
  • 代号替代词条:LZW的编码思想是不断地从字符流中提取新的字符串,通俗地理解为新“词条”,然后用代号也就是码字表示这个词条。这样一来,对字符流的编码就变成了用码字去替换字符流,生成码字流,从而达到压缩数据的目的。
  • 动态生成词典,新词条=旧词条+新字符:LZW编码是围绕称为词典的转换表来完成的。LZW编码器通过管理这个词典完成输入与输出之间的转换。
  • 输入字符流输出码字流:LZW编码器的输入是字符流,字符流可以是用8位ASCII字符组成的字符串,而输出是用n位(例如12位)表示的码字流。
过程

在这里插入图片描述

在这里插入图片描述

代码
  • 输入:字符流fp
  • 输出:码字流bf
void LZWEncode(FILE* fp, BITFILE* bf) {
   
	int character;	//C
	int string_code;//P
	int index;		//词典中的索引值
	unsigned long file_length;

	fseek(fp, 0, SEEK_END); //fp指针定位到文末
	file_length = ftell(fp);//获取输入文件长度
	fseek(fp, 0, SEEK_SET); //fp指针从新定位到开头
	BitsOutput(bf, file_length, 4 * 8);//输出的二进制文件
	
	InitDictionary();		//初始化词典
	string_code = -1;		//当前前缀p置空
    // 当前字符c=字符流中fp的下一个字符
	while (EOF != (character = fgetc(fp)))
	{
   
		//判断是否在字典当中,若在词典中返回索引值,若不在返回-1
		index = InDictionary(character, string_code);
		// 如果从词典中找到
		if
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值