compress.cpp

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

CPP
128
字号
// LZW compression// note changes needed to compile with g++#include <fstream.h>#include <iostream.h>#include <string.h>#include <stdlib.h>#include <math.h>#include "chash.h"// constantsconst D = 4099,      codes = 4096,  // 2^12      ByteSize = 8,      excess = 4,    // 12 - ByteSize      alpha = 256,   // 2^ByteSize      mask1 = 255,   // alpha - 1      mask2 = 15;    // 2^excess - 1class element {   friend void Compress();   public:      operator long() const {return key;}      element& operator =(long y)      {key = y; return *this;}   private:      int code;      long key;};// globalsint LeftOver, status = 0; ifstream in;ofstream out;void SetFiles(int argc, char* argv[]){// Create input and output streams.   char OutputFile[50], InputFile[50];   // see if file name provided   if (argc >= 2) strcpy(InputFile,argv[1]);   else {// name not provided, ask for it         cout << "Enter name of file to compress"              << endl;         cout << "File name should have no extension"                << endl;         cin >> InputFile;}   // name should not have an extension   if (strchr(InputFile,'.')) {       cerr << "File name has extension" << endl;       exit(1);}   // open files in binary mode   // in.open(InputFile,ios::binary);   in.open(InputFile); // for g++   if (in.fail()) {cerr << "Cannot open " << InputFile                         << InputFile << endl;                   exit(1);}   strcpy(OutputFile,InputFile);   strcat(OutputFile, ".zzz");   // out.open(OutputFile,ios::binary);    out.open(OutputFile); // for g++}void output(long code);void Compress(){// Lempel-Ziv-Welch compressor.   ChainHashTable<element, long> h(D);   element e;   for (int i = 0; i < alpha; i++) {// initialize      e.key = i;      e.code = i;      h.Insert(e);   }   int used = alpha; // codes used   // input and compress   unsigned char c;   in.get(c);   long pcode = c; // prefix code   if (!in.eof()) {// file length is > 1      do {// process rest of file          in.get(c);          if (in.eof()) break;  // finished          long k = (pcode << ByteSize) + c;          // see if code for k in dictionary          if (h.Search(k, e)) pcode = e.code;  // yes          else {// k not in table                output(pcode);                if (used < codes) // create new code                {e.code = used++;                 e.key = (pcode << ByteSize) | c;    				 h.Insert(e);}                pcode = c;}   	} while(true);      output(pcode);      if (status) {c = LeftOver << excess;                   out.put(c);}      }   out.close();   in.close();}void output(long pcode){// Output 8 bits, save rest in LeftOver.   unsigned char c,d;   if (status) {// 4 bits remain      d = pcode & mask1; // right ByteSize bits      c = (LeftOver << excess) | (pcode >> ByteSize);      out.put(c);      out.put(d);      status = 0;}   else {      LeftOver = pcode & mask2; // right excess bits      c = pcode >> excess;      out.put(c);      status = 1;}}void main(int argc, char* argv[]){   SetFiles(argc, argv);   Compress();}

⌨️ 快捷键说明

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