C/C++程序设计---RLE简单算法

C/C++程序设计—RLE简单算法

RLE算法压缩、解压文件(初级)
1.RLE概述
  RLE(Run Length Encoding行程编码)算法是一个简单高效的无损数据压缩算法。
  其基本思路是把数据看成一个线性序列,而这些数据序列组织方式分成两种情况:一种是连续的重复数据块,另一种是连续的不重复数据块。对于连续的重复数据块采用的压缩策略是用一个字节(我们称之为数据重数属性)表示数据块重复的次数,然后在这个数据重数属性字节后面存储对应的数据字节本身。
  例如某一个文件有如下的数据序列AAAAA,在未压缩之前占用5个字节,而如果使用了压缩之后就变成了5A,只占用两个字节,对于连续不重复的数据序列,表示方法和连续的重复数据块序列的表示方法一样,只不过前面的数据重数属性字节的内容为1。

2、压缩分析:
  了解了最基本的RLE算法后,压缩一个文件无非就是将重复的字节用一对数据来表示,即一个数据块[block],它为两个字节,第一个字节为个数,第二个字节为内容从而将文件变成很多个这样的块,(这对重复程度大的文件来说有较为理想的压缩效果,而内容像ABCABCABC的话使用这种算法文件会增大,就是1A1B1C1A1B1C1A1B1C了,更长,就达不到压缩的效果了,此处只讨论最基本的算法。)在这里插入图片描述

3、解压分析:
  由以上可知,源文件被压缩成了n个 [block]块,解压的过程就是将这些块一个一个释放出来即可,并写入新文件中。(第一个字节为写入的个数,第二个字节为写入的内容)。
在这里插入图片描述

4、运行实例:
在这里插入图片描述

演示:

如图,一个文件夹123.txt内容如下:
在这里插入图片描述

操作程序:
在这里插入图片描述

new.txt如下:
在这里插入图片描述

进行解压:
在这里插入图片描述

打开解压后的文件:

在这里插入图片描述

成功!
注:仅为最简单的RLE算法未做改进,如有不当之处,还请批评指正!

源代码如下:

#include<iostream>
using namespace std;
void compress(const char* src, const char* dest)//压缩
{
	FILE* fr = fopen(src, "rb");//二进制读取
	FILE* fw = fopen(dest, "wb");//二进制写入
	if (NULL == fr)
	{
		cout << "wrong!";
		return;
	}
	int count = 0;//记录相同字节的个数
	char samechar;//记录相同字节的内容
	char temp = fgetc(fr);//先获取第一个字节
	samechar = temp;
	while (temp !=EOF)
	{
		if (temp == samechar)
		{
			count++;//每当下一个字节与标志字节相同时,计数加一,并读取下一个字节
			temp = fgetc(fr);
			continue;
		}
		else//否则,写入文件,每一块有两个字节
		{
			fwrite(&count, 1, 1, fw);//保存个数
			fwrite(&samechar, 1, 1, fw);//保存内容
			//初始化标志字符和计数器
			samechar = temp;
			count = 0;
		}
	}
	//将文件结尾的一个或多个字节压缩至新文件
	if (count > 0)
	{
		fwrite(&count, 1, 1, fw);
		fwrite(&samechar, 1, 1, fw);
	}
	//关闭流
	fclose(fr);
	fclose(fw);
	cout << "压缩完成!";
}
void decompress(const char* src, const char* dest)//解压
{
	FILE* fr = fopen(src, "rb");
	FILE* fw = fopen(dest, "wb");
	if (NULL == fr)
	{
		cout << "wrong!";
		return;
	}
	char temp;
	int count;
	//解压很简单,每两个字节为一对,第一个为个数,第二个为内容
	while ((count = fgetc(fr)) != EOF)
	{
		temp = fgetc(fr);
		for (int i = 0; i < count; i++)
		{
			fwrite(&temp, 1, 1, fw);
		}
	}
	cout << "解压成功!";
	fclose(fr);
	fclose(fw);
}
int main()
{
	//用命令行来操作程序
	char src[100];
	char dest[100];
	char method='1';
	cout << "请输入命令:\n格式:rle file1 -c(-d) file2\n -c/-d代表压缩、解压\n";
	scanf("rle %s -%c %s", &src, &method, &dest);
	if (method == 'c')
	{
		compress(src, dest);
	}
	else if (method == 'd')
	{
		decompress(src, dest);
	}
	else
	{
		cout << "输入错误!\n"<<endl;
	}
}
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值