窗体顶端
窗体底端
LZ77 压缩算法实验报告
一、实验内容 :使用 C++编程实现 LZ77 压缩算法的实现。
二、 实验目的 :用 LZ77 实现文件的压缩。
三、 实验环境 : 1、软件环境:Visual C++ 6.0
2、编程语言:C++
四、 实验原理 : LZ77 算法在某种意义上又可以称为“滑动窗口压缩”,这是由于该算法将一个虚 拟的,可以跟随压缩进程滑动的窗口作为术语字 典,要压缩的字符串如果在该窗口 中出现,则输出其出现位置和长 度。使用固定大小窗口进行术语匹配,而不是在所 有已经编码的信 息中匹配,是因为匹配算法的时间消耗往往很多,必须限制字典的大小才能保证算法的效率;随着压缩的进程滑动字典窗口,使其中总包含最近编码过的信息,是因为对大多数信息而言,要编码的字符串往 往在最近的上下文中更容易到匹配串。
五、 LZ77 算法的基本流程 :1、从当前压缩位置开始,考察未编码的数据,并试图在滑动窗 口中出最长的匹 配字符串,如果到,则进行步骤2,否则进行步骤 3。
2、输出三元符号组 ( off, len, c )。其中 off 为窗口中匹 配字符串相对窗口边 界的偏移,len 为可匹配的长度,c 为下一个字符。然后将窗口向后 滑动 len + 1 个字符,继续步骤 1。
3、输出三元符号组 ( 0, 0, c )。其中 c 为下一个字符。 然后将窗口向后滑动 len + 1 个字符,继续步骤 1。
代码如下:
#include <windows.h>
#include <stdio.h>
#include <memory.h>
#include "lz77.h"
//////////////////////////////////////////////////////////////////
// out file format:
// 0;flag2;buffer;0;flag2;buffer;...flag1;flag2;bufferlast
// flag1 - 2 bytes, source buffer block length
// if block size is 65536, be zero
// flag2 - 2 bytes, compressed buffer length
// if can not compress, be same with flag1
//////////////////////////////////////////////////////////////////
void main(int argc, char* argv[])
{
/*if (argc != 4)
{
puts("Usage: ");
printf(" Compress : %s c sourcefile destfile\n", argv[0]);
printf(" Decompress : %s d sourcefile destfile\n", argv[0]);
return;
} */
BYTE soubuf[65536];
BYTE destbuf[65536 + 16];
FILE* in;
FILE* out;
/* in = fopen("", "rb");
if (in == NULL)
{
puts("Can't open source file");
return;
}
out = fopen("", "wb");
if (out == NULL)
{
puts("Can't open dest file");
fclose(in);
return;
}
fseek(in, 0, SEEK_END);
long soulen = ftell(in);
fseek(in, 0, SEEK_SET);
CCompressLZ77 cc;
WORD flag1, flag2; */
int temp;
printf("compress(0) or decompress(1)?:");
scanf("%d",&temp);
if (temp == 0) // compress
{
in = fopen("", "rb");
if (in == NULL)
{
puts("Can't open source file");
return;
}
out = fopen("", "wb");
if (out == NULL)
{
puts("Can't open dest file");
fclose(in);
return;
}
fseek(in, 0, SEEK_END);
long soulen = ftell(in);
fseek(in, 0, SEEK_SET);
CCompressLZ77 cc;
WORD flag1, flag2;
int last = soulen, act;
while ( last > 0 )
{
act = min(65536, last);
fread(soubuf, act, 1, in);
last -= 字符串长度压缩act;
if (act == 65536) // out 65536 bytes
flag1 = 0;
else // out last blocks
flag1 = act;
fwrite(&flag1, sizeof(WORD), 1, out);
int destlen = cc.Compress((BYTE*)soubuf, act, (BYTE*)destbuf);
if (destlen == 0) // can't compress the block
{
flag2 = flag1;
fwrite(&flag2, sizeof(WORD), 1, out);
fwrite(soubuf, act, 1, out);
}
else
{
flag2 = (WORD)destlen;
fwrite(&flag2, sizeof(WORD), 1, out);
fwrite(destbuf, destlen, 1, out);
}
}
}
else if (temp == 1) // decompress
{
in = fopen("", "rb");
if (in == NULL)
{
puts("Can't open source file");
return;
}
out = fopen("", "wb");
if (out == NULL)
{
puts("Can't open dest file");
fclose(in);
return;
}
fseek(in, 0, SEEK_END);
long soulen = ftell(in);
fseek(in, 0, SEEK_SET);
CCompressLZ77 cc;
WORD flag1, flag2;
int last = soulen, act;
while (last > 0)
{
fread(&flag1, sizeof(WORD), 1, in);
fread(&flag2, sizeof(WORD), 1, in);
last -= 2 * sizeof(WORD);
if (flag1 == 0)
act = 65536;
else
act = flag1;
last-= flag2 ? (flag2) : act;
if (flag2 == flag1)
{
fread(soubuf, act, 1, in);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论