找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3257|回复: 3

【C】使用霍夫曼树压缩数据

[复制链接]
发表于 2020-11-7 18:26:38 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
以下介绍使用StoneValley库的霍夫曼树进行数据的压缩和解压缩。
霍夫曼压缩算法位于StoneValley库的/src/svctree.c文件内。
压缩前和压缩后的数据存储在比特流(BITSTREAM)结构体内。
示例使用了treHuffmanEncoding对数据进行压缩,使用了treHuffmanDecoding解压缩数据。
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "../src/svdef.h"
  4. #include "../src/svstring.h"
  5. #include "../src/svtree.h"

  6. static const unsigned char sdata[] = { /* Prepared and compressed data. */
  7.         0xE4, 0x4E, 0x0F, 0x56, 0x27, 0x71, 0x5A, 0xF7,
  8.         0x1F, 0x2F, 0x59, 0xBF, 0xEE, 0x0F, 0x6A, 0x63,
  9.         0x0F, 0x66, 0xE3, 0x93, 0x17, 0xA5, 0x9E, 0xB5,
  10.         0x92, 0x5A, 0x3B, 0x6C, 0xAC, 0x88, 0x4D, 0x77,
  11.         0x39, 0xAB, 0x09, 0x16, 0x7D, 0x8B, 0x53, 0xB3,
  12.         0x37, 0xC3, 0xF5, 0xA8, 0x4C, 0x56, 0x61, 0xD7,
  13.         0xCA, 0xFE, 0x92, 0x90
  14. };

  15. static const HFM_SYMBOL stabl[] = { /* Prepared symbol table. */
  16.         0040, 0002, 0000, 0145, 0003, 0003, 0164, 0004,
  17.         0017, 0157, 0004, 0013, 0151, 0004, 0012, 0150,
  18.         0004, 0005, 0141, 0004, 0004, 0163, 0005, 0031,
  19.         0154, 0005, 0030, 0156, 0005, 0020, 0143, 0005,
  20.         0021, 0000, 0005, 0022, 0144, 0006, 0047, 0162,
  21.         0006, 0073, 0147, 0006, 0046, 0111, 0006, 0071,
  22.         0155, 0006, 0070, 0123, 0007, 0157, 0077, 0007,
  23.         0164, 0126, 0007, 0155, 0056, 0007, 0156, 0160,
  24.         0007, 0152, 0146, 0007, 0153, 0124, 0007, 0150,
  25.         0047, 0007, 0165, 0166, 0007, 0151, 0171, 0007,
  26.         0154
  27. };

  28. /* Strings. */
  29. static const char * pstr[2] = {"Hello, ", "library."};

  30. /* This's a tricky function. */
  31. int foo(void)
  32. {
  33.         P_ARRAY_Z ptbl;
  34.         BITSTREAM bsin;
  35.         P_BITSTREAM pbsout;
  36.         if (NULL == strInitBitStream(&bsin))
  37.                 return __LINE__; /* Can not initialize bit-stream. */
  38.         if (NULL == (ptbl = strCreateArrayZ(sizeof(stabl), sizeof(HFM_SYMBOL))))
  39.                 return __LINE__; /* Can not initialize array. */
  40.         /* Set bsin and symbol table up. */
  41.         bsin.bilc = 5; /* This number is recorded after encoding. */
  42.         strResizeArrayZ(&bsin.arrz, sizeof(sdata), sizeof(UCHART));
  43.         memcpy(bsin.arrz.pdata, sdata, sizeof(sdata));
  44.         memcpy(ptbl->pdata, stabl, sizeof(stabl));
  45.         /* Decode and display. */
  46.         pbsout = treHuffmanDecoding(ptbl, &bsin);
  47.         printf("%s%s\n", (char *)pbsout->arrz.pdata, pstr[1]);
  48.         /* Cleanup. */
  49.         strDeleteBitStream(pbsout);
  50.         /* Don't delete bsin here. Free bsin. */
  51.         strFreeBitStream(&bsin);
  52.         strDeleteArrayZ(ptbl);
  53.         return 0;
  54. }

  55. /* This function illustrates how to use Huffman algorithm to compress data. */
  56. int main(void)
  57. {
  58.         P_ARRAY_Z ptbl = NULL; /* Used to store a symbol table. */
  59.         P_BITSTREAM pbsout, pbsin; /* Bit-streams that used to contain data. */
  60.         /* Encode string 'hello'. Caution that table is important for decoding. */
  61.         if (NULL == (pbsin = treHuffmanEncoding(&ptbl, (const PUCHAR)pstr[0], 8)))
  62.         {
  63.                 fprintf(stderr, "Error! Can not Encode.\n");
  64.                 return __LINE__;
  65.         }
  66.         if (NULL == (pbsout = treHuffmanDecoding(ptbl, pbsin)))
  67.         {
  68.                 fprintf(stderr, "Error! Can not Decode.\n");
  69.                 return __LINE__;
  70.         }
  71.         /* Print hello. */
  72.         printf("%s", (char *)pbsout->arrz.pdata);
  73.         /* Don't forget to free bit-streams and symbol table after use. */
  74.         strDeleteBitStream(pbsout);
  75.         strDeleteBitStream(pbsin);
  76.         strDeleteArrayZ(ptbl);
  77.         return foo();
  78. }
复制代码

比特流pbsout中包含了97Bytes的数据,压缩后的sdata全局变量只包含52Bytes的数据。
但是因为数据量小还要加上全局变量stabl内包含的符号表所以体现不出压缩的优势。

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2020-11-7 23:41:16 | 显示全部楼层
我还以为你自己实现了Huffman压缩算法呢
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2020-11-8 08:46:36 | 显示全部楼层
0xAA55 发表于 2020-11-7 23:41
我还以为你自己实现了Huffman压缩算法呢

霍夫曼算法在StoneValley库里面实现了,而且是开源的。要把实现代码贴出来吗?
回复 赞! 靠!

使用道具 举报

发表于 2020-11-8 08:57:15 | 显示全部楼层
new_starter 发表于 2020-11-8 08:46
霍夫曼算法在StoneValley库里面实现了,而且是开源的。要把实现代码贴出来吗? ...

站长说的是你自己实现的Huffman算法......
就像我这样:https://www.0xaa55.com/thread-16843-1-1.html
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 18:07 , Processed in 0.030636 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表