V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
CBBing
V2EX  ›  问与答

求助,怎么将编码结果用 bit 位存到文件中

  •  
  •   CBBing · 2015-01-02 21:52:33 +08:00 · 2513 次点击
    这是一个创建于 3620 天前的主题,其中的信息可能已经有所发展或是发生改变。
    对一篇英文文章出现的字符进行Huffman编码,然后要将编码表和英文文章保存到文件中,编码结果必须是二进制形式,即0和1要用bit位表示,不能用字符'0'和‘1’表示
    21 条回复    2015-01-03 10:46:01 +08:00
    xenme
        1
    xenme  
       2015-01-02 22:08:51 +08:00
    8bit合成一个byte写入binary文件就好了~
    CBBing
        2
    CBBing  
    OP
       2015-01-02 22:22:37 +08:00
    @xenme 我也有想过这种方法,可是怎么合成呢?
    ryd994
        3
    ryd994  
       2015-01-02 22:30:35 +08:00
    +
    <<
    +
    <<
    就这样……
    zealic
        4
    zealic  
       2015-01-02 22:31:15 +08:00
    File Format:
    Magic Header: 0xBB110000 // uint32
    Data Length: data size // uint32
    Padding bit size: 0-8 // ushort
    Data: <YOUR HUFFMAN ENCODED DATA>
    xenme
        5
    xenme  
       2015-01-02 22:33:31 +08:00
    @CBBing 参考 @ryd994
    移位即可
    CBBing
        6
    CBBing  
    OP
       2015-01-02 22:34:51 +08:00
    @zealic 不好意思,能不能解释一下,不大理解
    CBBing
        7
    CBBing  
    OP
       2015-01-02 22:35:26 +08:00
    @ryd994 ......
    zealic
        8
    zealic  
       2015-01-02 22:36:42 +08:00
    @CBBing 补习一下计算机导论吧
    ryd994
        9
    ryd994  
       2015-01-02 22:44:35 +08:00
    @CBBing 首先说说你用的什么语言, 还有计算完成时的结果数据是什么样子什么类型的吧
    不过大多数语言用wb模式打开文件就可以了
    CBBing
        10
    CBBing  
    OP
       2015-01-02 22:59:30 +08:00
    @ryd994 我用的C跟c++,程序完成时应该有所有字符的Huffman编码(这个倒不难),主要是要求用bit位存储,就是将Huffman编码的0和1用bit类型存储(如果用字符的话也不难)。
    ryd994
        11
    ryd994  
       2015-01-02 23:27:31 +08:00
    @CBBing c++ 有bit数据类型?你出来结果是什么数据类型?int?bool?
    CBBing
        12
    CBBing  
    OP
       2015-01-02 23:47:56 +08:00
    @ryd994 我Huffman编码后的数据是字符组的,比如说字符a的编码是001001,都是字符的,现在要把它用bit类型的表示,我的一个思路是,把它用short类型的整形存储,这样可以通过读取的数字知道所存的是什么,虽然有所缩减内存,但比起要求还是差一点
    nilennoct
        13
    nilennoct  
       2015-01-02 23:48:26 +08:00 via iPad   ❤️ 1
    抛砖引玉==buffer也可以开大点,比如byteBuf[32],再拿个变量记录bufOffset。。。

    ``` c++
    ofstream outputBinFile;
    char byteBuf = '\0';
    short bitOffset = 7;

    while (data not output completely) {
    byteBuf |= {your data here(0 or 1)} << bitOffset;
    if (bitOffset == 0) {
    outputBinFile.write(&byteBuf, 1);
    byteBuf = '\0';
    bitOffset = 7;
    }
    else {
    --bitOffset;
    }
    }

    // output the rest data
    if (bitOffset < 7) {
    outputBinFile.write(&byteBuf, 1);
    }
    ```
    nilennoct
        14
    nilennoct  
       2015-01-02 23:51:00 +08:00 via iPad
    对了 buffer用char*的话也要记得每次用前先填零
    CBBing
        15
    CBBing  
    OP
       2015-01-02 23:51:28 +08:00
    @ryd99 举个例子,字符a的Huffman编码是001001,要求是将其存到文件中,只占用6个bit,但我做的是将它变成00100100,用了8个bit,而且有可能还会有冲突
    CBBing
        16
    CBBing  
    OP
       2015-01-02 23:54:31 +08:00
    @nilennoct 谢谢,这个貌似是java的吧,我是用C或C++的,这个感觉不太好实现吧
    CBBing
        17
    CBBing  
    OP
       2015-01-02 23:55:31 +08:00
    @nilennoct 看错了,sorry
    choury
        18
    choury  
       2015-01-02 23:56:18 +08:00 via Android
    我写过一个动态haffuman的程序,不过声明一点,你自己看吧,我不负责你能不能看懂,也就是不会给你讲解
    https://gist.github.com/choury/a68006b3fe1a6a78e29d
    CBBing
        19
    CBBing  
    OP
       2015-01-03 00:00:15 +08:00
    @choury 有注释吗?
    choury
        20
    choury  
       2015-01-03 00:02:58 +08:00 via Android   ❤️ 1
    @CBBing 代码都给了,自己看呗,你要的内容主要在compress这个函数里面
    ryd994
        21
    ryd994  
       2015-01-03 10:46:01 +08:00
    @CBBing 6位的话,用一个char[3]这样就是4个6bit
    然后6+2 4+4 2+6这样填进去
    假如说你有data1-4
    那就是
    buffer[0] = data3<<6 + data4
    buffer[1] = data2<<4 + data3>>2
    buffer[2] = data1<<2 + data2>>4
    这样应该就可以了
    不过感觉太恶心了,我再看看其他办法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   924 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 21:38 · PVG 05:38 · LAX 13:38 · JFK 16:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.