⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compress.cpp

📁 常用算法与数据结构原代码
💻 CPP
字号:
// 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"

// constants
const D = 4099,      // hash function divisor
      codes = 4096,  // 2^12
      ByteSize = 8,
      excess = 4,    // 12 - ByteSize
      alpha = 256,   // 2^ByteSize
      mask1 = 255,   // alpha - 1
      mask2 = 15;    // 2^excess - 1

class element {
   friend void Compress();
   public:
      operator unsigned long() const {return key;}
      element& operator =(unsigned long y)
         {key = y; return *this;}
   private:
      int code;
      unsigned long key;
};

// globals
int LeftOver,   // code bits yet to be output
    status = 0; // 0 means no bits in LeftOver
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(unsigned long code);

void Compress()
{// Lempel-Ziv-Welch compressor.
   // define and initialize the code dictionary
   ChainHashTable<element, unsigned 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; // number of codes used

   // input and compress
   unsigned char c;
   in.get(c);      // first character of input file
   unsigned 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
          unsigned long k = (pcode << ByteSize) + c;
          // see if code for k is in the 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 last code(s)
      Output(pcode);
      if (status) {c = LeftOver << excess;
                   out.put(c);}
      }

   out.close();
   in.close();
}

void Output(unsigned 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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -