繁体   English   中英

使用按位运算符在 C++ 中进行压缩

[英]Compression in c++ using bitwise operators

我们得到了一项任务,其中我们必须将 4 个字节压缩为 3 个字节。 它希望我们通过将字符打包成 6 位而不是 8 位来压缩 25%。 它应该是 25% 的精确压缩,但我的程序执行了大约 50%。 Code Book 是我自己的“ASCII”表,按位运算符用于执行压缩。 有谁知道为什么将其压缩 50% 而不是 25%? 我知道 namespace std 不是一个好习惯,但我们被要求使用它。 谢谢!`

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

unsigned char CodeBook[53][2];

unsigned char FindCharacterCode(unsigned char C)
{
   for (int j = 0; j < 53; j++)
   if (CodeBook[j][0] == C)
   return CodeBook[j][1];
   return 0;
}

void MyCodeBook()
{
    CodeBook[0][0] = 'a'; CodeBook[0][1] = 1;
    CodeBook[1][0] = 'b'; CodeBook[1][1] = 2;
    CodeBook[2][0] = 'c'; CodeBook[2][1] = 3;
    CodeBook[3][0] = 'd'; CodeBook[3][1] = 4;
    CodeBook[4][0] = 'e'; CodeBook[4][1] = 5;
    CodeBook[5][0] = 'f'; CodeBook[5][1] = 6;
    CodeBook[6][0] = 'g'; CodeBook[6][1] = 7;
    CodeBook[7][0] = 'h'; CodeBook[7][1] = 8;
    CodeBook[8][0] = 'i'; CodeBook[8][1] = 9;
    CodeBook[9][0] = 'j'; CodeBook[9][1] = 10;
    CodeBook[10][0] = 'k'; CodeBook[10][1] = 11;
    CodeBook[11][0] = 'l'; CodeBook[11][1] = 12;
    CodeBook[12][0] = 'm'; CodeBook[12][1] = 13;
    CodeBook[13][0] = 'n'; CodeBook[13][1] = 14;
    CodeBook[14][0] = 'o'; CodeBook[14][1] = 15;
    CodeBook[15][0] = 'p'; CodeBook[15][1] = 16;
    CodeBook[16][0] = 'q'; CodeBook[16][1] = 17;
    CodeBook[17][0] = 'r'; CodeBook[17][1] = 18;
    CodeBook[18][0] = 's'; CodeBook[18][1] = 19;
    CodeBook[19][0] = 't'; CodeBook[19][1] = 20;
    CodeBook[20][0] = 'u'; CodeBook[20][1] = 21;
    CodeBook[21][0] = 'v'; CodeBook[21][1] = 22;
    CodeBook[2][0] = 'w'; CodeBook[22][1] = 23;
    CodeBook[23][0] = 'x'; CodeBook[23][1] = 24;
    CodeBook[24][0] = 'y'; CodeBook[24][1] = 25;
    CodeBook[25][0] = 'z'; CodeBook[25][1] = 26;
    CodeBook[26][0] = '0'; CodeBook[26][1] = 27;
    CodeBook[27][0] = '1'; CodeBook[27][1] = 28;
    CodeBook[28][0] = '2'; CodeBook[28][1] = 29;
    CodeBook[29][0] = '3'; CodeBook[29][1] = 30;
    CodeBook[30][0] = '4'; CodeBook[30][1] = 31;
    CodeBook[31][0] = '5'; CodeBook[31][1] = 32;
    CodeBook[32][0] = '6'; CodeBook[32][1] = 33;
    CodeBook[33][0] = '7'; CodeBook[33][1] = 34;
    CodeBook[34][0] = '8'; CodeBook[34][1] = 35;
    CodeBook[35][0] = '9'; CodeBook[35][1] = 36;
    CodeBook[36][0] = '!'; CodeBook[36][1] = 37;
    CodeBook[37][0] = '$'; CodeBook[37][1] = 38;
    CodeBook[38][0] = '('; CodeBook[38][1] = 39;
    CodeBook[39][0] = ')'; CodeBook[39][1] = 40;
    CodeBook[40][0] = '#'; CodeBook[40][1] = 41;
    CodeBook[41][0] = '&'; CodeBook[41][1] = 42;
    CodeBook[42][0] = '%'; CodeBook[42][1] = 43;
    CodeBook[43][0] = '-'; CodeBook[43][1] = 44;
    CodeBook[44][0] = '.'; CodeBook[44][1] = 45;
    CodeBook[45][0] = ','; CodeBook[45][1] = 46;
    CodeBook[46][0] = '\''; CodeBook[46][1] = 47;
    CodeBook[47][0] = ';'; CodeBook[47][1] = 48;
    CodeBook[48][0] = ':'; CodeBook[48][1] = 49;
    CodeBook[49][0] = '?'; CodeBook[49][1] = 50;
    CodeBook[50][0] = ' '; CodeBook[50][1] = 51;
    CodeBook[51][0] = ' '; CodeBook[51][1] = 52;
    CodeBook[52][0] = '¶'; CodeBook[52][1] = 53;

}

int main()
{

     MyCodeBook();

     ifstream In;
     ofstream Out;

     In.open("C://Users//osama//Desktop//code.txt");
     Out.open("C://Users//osama//Desktop//compressed.txt");

     unsigned char Data[4] = { 0 },
     Compressed[3] = { 0 }, Code[4] = { 0 };
     int i; 

     while (!In.eof())
     {

         if (In.is_open())
         {
             for (i = 0; i < 4; i++)
             {
                 In >> Data[i];
                 Code[i] = FindCharacterCode(Data[i]);
             }
         }
         else
         {
             cout << "Not open!" << endl << endl;
             return -1;
         }

         Compressed[0] = Code[0] << 2;
         Compressed[0] = (Compressed[0] | Code[1] >> 4);

         Compressed[1] = (Code[1] << 4);
         Compressed[1] = (Compressed[1] | Code[2] >> 2);

         Compressed[2] = (Code[2] << 6);
         Compressed[2] = Compressed[2] | Code[3];

         for (i = 0; i < 3; i++)
         {
              Out << Compressed[i];
         }

     }

     In.close();
     Out.close();



     return 0;
 }

暗示:

对于压缩算法的任何给定输入,您将获得一个介于 1 和 53 之间的数字(我们称之为 0 和 53)。

我们需要多少位才能适应这么大的数字?

1? 在一位中,我们可以存储 0 到 1 - 太小了。

2? 在 2 位中,我们可以存储 0 到 3 - 太小了。

...

5? 在 5 位中,我们可以存储 0 到 31 - 太小了。

6? 在 6 位中,我们可以存储 0 到 63 - 足够大。

输入是字符或字节 - 8 位。

6 / 8 * 100 = 75%

这是您的 25% 压缩率。

现在您需要弄清楚如何将 4 个 6 位的批次编码为 3 个 8 位的字节。

这就是您的按位运算符(和一些位移)的用武之地。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM