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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM