• C语言课程设计---RLE压缩算法


    C语言课程设计---RLE压缩算法

    RLE算法的介绍

    RLE全称(run-length encoding),翻译为游程编码,又译行程长度编码,又称变动长度编码法(run coding),在控制论中对于二值图像而言是一种编码方法,对连续的黑、白像素数(游程)以不同的码字进行编码。游程编码是一种简单的非破坏性资料压缩法,其好处是加压缩和解压缩都非常快。其方法是计算连续出现的资料长度压缩之。

    如图为RLE算法描述

    RLE在用于二进制多重复的情况下比较好, 特点是可以做到无损压缩, 但是用于字符多且重复性差的情况下可能做到事倍功半, 比如 ABCDEFG经压缩后将成为1A1B1C1D1E1F1G, 字符串整整扩大了一倍.


    c语言实现

    为了模拟出有重复性的数据, 我以如下方式进行数据生成:

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
    	freopen("file.txt","w",stdout);	//输出重定向,输出到文件
    	srand(time(0));	//以当前时间作为种子
    	char x;
    	for(int i = 0; i <= 10000000; ++i){
    		x = 'a' + rand()%26;
    		cout<<x<<x<<x<<x;
    	}
    	return 0;
    }
    
    

    RLE算法代码:

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

    命令行参数如下

    rle file1 –c(-d) file2

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

    #include<bits/stdc++.h>
    using namespace std;
    
    void zip(char* filename,char *outfile){
    	FILE *in, *out;
    	int filelen;
    	char cur, tmp;	
    	if(!(in = fopen(filename,"rb")))
    		cout<<"文件打开失败"<<endl;
    	else
    	{
    		out = fopen(outfile,"wb");
    		cur = fgetc(in);
    		tmp = cur;
    		filelen = 1;
    		while(!feof(in)){
    			cur = fgetc(in);
    			if(cur == tmp){
    				filelen++;
    			}
    			else{
    				fputc(filelen+'0',out);
    				fputc(tmp,out);
    				tmp = cur;
    				filelen = 1;
    			}
    		}
    	}
    	fclose(in);
    	fclose(out);
    }	
    
    void unzip(char *filename,char *outfile){
    	FILE *in, *out;
    	int filelen;
    	char cur;	//光标
    	if(!(in = fopen(filename,"rb")))
    		cout<<"文件打开失败"<<endl;
    	else
    	{
    		out = fopen(outfile,"wb");
    		while(!feof(in)){
    			filelen = fgetc(in)-'0';
    			if(feof(in))break;	//feof的问题,折腾了好一会,不好表述,总之在feof应当在每一次读操作之后判断是否到文件末, 不然会造成多读一次的错误
    			cur = fgetc(in);
    			while(filelen--)
    				fputc(cur,out);
    		}
    	}
    	fclose(in);
    	fclose(out);
    }	
    
    
    int main(int argc,char *argv[]){
    	if(!strcmp(argv[2], "-d")){
    		unzip(argv[1], argv[3]);
    		cout<<"decompress finished"<<endl;
    	}
    
    	else if(!strcmp(argv[2],"-c")){
    		zip(argv[1], argv[3]);
    		cout<<"compress finished"<<endl;
    	}
    	else
    		cout<<"输入参数有误,请重新检查,-c : compress; -d : decompress"<<endl; 
    	return 0;
    }
    

    其中应用到了两个之前没用过的函数fgetc和fputc, 这里简单记录一下:

    fgetc是一种计算机C语言中的函数。意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。
    函数格式:int fgetc(FILE *stream)
    
    fputc函数功能: 将字符ch写到文件指针fp所指向的文件的当前写指针的位置。
    函数格式:int fputc (int c, FILE *fp)
    

    结果:

    源文件----35MB

    压缩后文件----15MB

  • 相关阅读:
    redis.conf 配置信息:读取及修改命令
    Redis 持久化
    webpack 中,module、chunk、bundle 的区别(待补充)
    对象属性的描述:writable、enumerable、configurable
    webpack 中,importloaders 配置项的含义
    vue cli 3 中,Lint on save 与 Lint and fix on commit 区别(待补充)
    使用 vue-cli-service inspect 来查看一个 Vue CLI 3 项目的 webpack 配置信息(包括:development、production)
    Eslint 能自动格式化代码,为什么还要用 Prettier?
    prettier-eslint 与 prettier-eslint-cli 区别
    032_nginx配置文件安全下载
  • 原文地址:https://www.cnblogs.com/roccoshi/p/13030639.html
Copyright © 2020-2023  润新知