西电C语言程序设计实验之RLE解压缩算法

RLE压缩解压算法

编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压。

命令行参数如下:

rle file1 –c(-d) file2

第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名。

算法分析

压缩算法分析

每次从文件读取一定的字节到inputByte中,对这一部分的字节进行解析,每次读取一个字节如果出现连续三个字节相等则进行计数,注意总数不能超过127个(二进制八位表示范围是**-128到127**)。将总共重复的字节数大小与0x80按位或,即取后七位并把第八位置为一,作为压缩标记,存入outputByte,再把重复的字节对象存入。若是其他情况则直接写入字节即可。

代码实现:

int Encode(unsigned char* inputByte, unsigned char* outputByte){
	unsigned char *in = inputByte, *out = outputByte;
	int left = strlen(inputByte), size = 0;
	while(left > 0){
		if(left < 3){
			out[size++] = *in++;
			left--;
		}else if(in[0] == in[1] && in[1] == in[2]){
			int i = 0, len = 1; 
			while(i < left - 1 && len < 127){//二进制八位表示范围是-128到127,最大数位为127 
				if(in[i] == in[i+1]){
					len++;	i++;
				}else	break;
			}
			out[size++] = len|0x80;//与0x80即二进制10000000按位或 取后七位并把第八位置为一 作为压缩标记 
			out[size++] = *in;
			in += len;	
			left -= len;
		}else{
			out[size++] = *in++;	
			left--;
		}
	}
	return size;
}
解压缩算法分析

同样读取字节并对该部分字节解析,每次读取一个字节,和0x80按位与,如果有压缩标记,则结果会等于0x80(由ASCLL码可以知道,其他没被标记的字节最大也一定小于0x80),那么就再把该字节与0x7f按位或,即取下二进制后七位数,也就是重复字节的数量,然后进行读入即可。如果不是标记就直接读入该处字节。

代码实现:

int Decode(unsigned char* inputByte, unsigned char* outputByte){
	unsigned char *in = inputByte, *out = outputByte;
	int i = 0, size = 0;
	while(i < strlen(inputByte)){
		//这里按位与运算必须加上括号 否则就变成了in[i]&(0x80==0x80)因为优先级==高于&
		if((in[i] & 0x80) == 0x80){//如果有压缩标记 则与0x80按位与后会等于0x80
			int c = in[i] & 0x7f;//取下后七位数 即重复字节的数量
			i++;
			while(c--)	out[size++] = in[i];
			i++;
		}else{
			out[size++] = in[i++];
		}
	}
	return size;
}

程序结构解释

  1. 两个文件指针inputFileoutputFile分别指向初始文件和目标文件。

  2. 两个char*型指针inputByteoutputByte,inputByte负责从inputFile中读取字节,outputByte负责读入处理过后的字节。

  3. Solve函数进行处理压缩或则解压缩命令并进行文件读取读出,压缩则利用Encode函数进行编码,解压缩则利用Decode函数进行解码。

程序运行结果

在这里插入图片描述

在这里插入图片描述

二进制查看分析:

在这里插入图片描述

在这里插入图片描述

后记

完整源码详见我的github项目:xdu-exp-c

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

akynazh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值