1

我正在实现 Shannon-Fano 编码算法,我想将符号代码输出为位。

例如,在下面的代码中,我fin逐行读取输入文件(流)中的符号,用算法形成的std::string符号代码(from )填充,然后用. 然后我尝试输出位集,但在输出文件中,位集中的每个“真”或“假”值占用 1 个字节而不是 1 位。std::map<unsigned short, std::string> symbolCodesboost::dynamic_bitsetcurrentOutString

if (fin.is_open() && fout.is_open()) {
    std::string currentInString;
    std::string currentOutString;

    while (getline(fin, currentInString)) {
        boost::dynamic_bitset<> bitSet;
        for (auto & ref : currentInString) {
            currentOutString += symbolCodes[ref];
        }

        for (auto & ref : currentOutString) {
            if (ref == '0') bitSet.push_back(0);
            if (ref == '1') bitSet.push_back(1);
        }
        fout << bitSet;

        bitSet.clear();
        currentOutString.erase();
    }
}

fout流以std::ios_base::binary模式打开。例如,我有单词“file”,代码是e: 00, f: 01, i: 10, l: 11. 如何输出我的位集,所以输出文件占用 8 位而不是 8 字节?

提前感谢您的帮助,并对可能的语言错误表示歉意。

4

1 回答 1

2

这实际上不是dynamic_bitset' 的错;是iostream的。

以下代码打印

123
----.

cout

#include <iostream>
#include <boost/dynamic_bitset.hpp>

int main() {
    using namespace std;
    using namespace boost;

    auto bitset = dynamic_bitset<>(32, 0x0a333231); // "123\n" in little endian
    bitset.append(0x2d2d2d2d); // "----"
    bitset.append(0x0a2e); // ".\n"
    // bitset.size() is at least 96 here

    auto ulong_mask = dynamic_bitset<>(bitset.size(), 0xFFFFFFFFul);
    while(bitset.any()) {
        unsigned long ulong = (bitset & ulong_mask).to_ulong();
        cout.write(reinterpret_cast<char*>(&ulong), sizeof(ulong));

        bitset >>= 32;
    }
}

注意使用cout.write()代替operator <<它按原样输出字节,没有任何格式和转换为 ASCII 字符串(想想itoa()或类似的东西)。


还有一点:因为dynamic_bitset不提供连续的存储保证和/或访问,我们必须逐块读取大的位集,最好是更大的尺寸;例如unsigned long

在某些架构上,sizeof(unsigned long)将是 8,因此我们实际上可以使用更大的ulong_maskULONG_MAX会做),并(8 * sizeof(unsigned long))相应地移动。用那个。(为了清晰起见,上面的 32 是硬编码的)。

于 2013-09-29T14:57:15.607 回答