decomp.cpp

来自「一本全面剖析C++数据结构算法的书籍」· C++ 代码 · 共 134 行

CPP
134
字号
// Decompress using Ziv-Lempel-Welch// note changes needed to compile with g++#include <fstream.h>#include <iostream.h>#include <string.h>#include <stdlib.h>#include <math.h>class element {   friend void decompress();   friend void output(int);   private:      int prefix;      unsigned char suffix;};// constantsconst codes = 4096,  // 2^12      ByteSize = 8,      excess = 4,    // 12 - ByteSize      alpha = 256,   // 2^ByteSize      mask = 15;     // 2^excess - 1// globalsunsigned char s[codes];  // used to reconstruct textint size,                // size of reconstructed text    LeftOver,            // left over bits from last code    status = 0;          // 0 iff no left over bitselement ht[codes];       // dictionaryifstream in;ofstream out;void SetFiles(int argc, char* argv[]){// Determine file name.   char OutputFile[50], InputFile[50];   // see if file name provided   if (argc == 2) strcpy(OutputFile,argv[1]);   else {// name not provided, ask for it         cout << "Enter name of file to decompress"              << endl;         cout << "Omit the extension .zzz"  << endl;         cin >> OutputFile;}   // name should not have an extension   if (strchr(OutputFile,'.'))      {cerr << "File name has extension" << endl;       exit(1);}   strcpy(InputFile, OutputFile);   strcat(InputFile, ".zzz");   // open files in binary mode   // in.open(InputFile,ios::binary);    in.open(InputFile);  // for g++   if (in.fail()) {cerr << "Cannot open "                        << InputFile  << endl;                   exit(1);}   // out.open(OutputFile,ios::binary);    out.open(OutputFile); // for g++}bool GetCode(int& code);void output(int code);void decompress(){// Decompress a compressed file.   int used = alpha; // codes used so far   // input and decompress   int pcode,  // previous code       ccode;  // current code   if (GetCode(pcode)){// file is not empty      s[0] = pcode;   // character for pcode       out.put(s[0]);  // output string for pcode      size = 0; // s[size] is first character of                // last string output                      while(GetCode(ccode)) {// get another code        if (ccode < used) {// ccode is defined           output(ccode);           if (used < codes) {// create new code              ht[used].prefix = pcode;   	      ht[used++].suffix = s[size];}}        else {// special case, undefined code              ht[used].prefix = pcode;              ht[used++].suffix = s[size];              output(ccode);}        pcode = ccode;}}   out.close();   in.close();}bool GetCode(int& code){// Put next code in compressed file into code. // Return false if no more codes.   unsigned char c, d;   in.get(c);  // input 8 bits   if (in.eof()) return false;  // no more codes   // see if any left over bits from before   // if yes, concatenate with left over 4 bits   if (status) code = (LeftOver << ByteSize) | c;   else {// no left over bits, need four more bits         // to complete code         in.get(d);  // another 8 bits         code = (c << excess) | (d >> excess);         LeftOver = d & mask;}  // save 4 bits   status = 1 - status;   return true;}   void output(int code){// Output string corresponding to code.   size = -1;   while (code >= alpha) {// suffix in dictionary      s[++size] = ht[code].suffix;      code = ht[code].prefix;}   s[++size] = code;  // code < alpha   // decompressed string is s[size] ... s[0]   for (int i = size; i >= 0; i--)      out.put(s[i]);}void main(int argc, char* argv[]){   SetFiles(argc, argv);   decompress();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?