从字符串向量填充boost :: dynamic_bitset <>的最快方法

时间:2018-12-02 23:13:24

标签: c++ boost-dynamic-bitset

我正在实现一个使用霍夫曼编码来压缩文件的程序。我在将压缩字符串的位写入另一个位集时遇到麻烦。我有一个字节向量(8位整数)和一个字符串huffCodes向量,其大小为256,用于存储每个索引的位字符串。 (例如,0表示为11,1表示为11011,依此类推。)

这是我当前的方法:

string compressed = "";
boost::dynamic_bitset<unsigned char> output;

for(byte b : bytes) 
{
    compressed += huffCodes [ ByteToInt(std::to_string(b)) ];
}

output = boost::dynamic_bitset<unsigned char> (compressed);

这遍历每个字节,并从huffCodes向量中获取其对应的位字符串,然后将该字符串附加到压缩的字符串中。压缩的字符串完成后,会将其转换为位集。这种方法的问题在于它会缓慢填充位集,因为我的向量中有7200万个字节。但我不喜欢这种方法,因为似乎不必填充这个巨大的字符串以将其转换为位集。我希望这样的事情:

boost::dynamic_bitset<unsigned char> output;
string temp = "";
    for(byte b : bytes) 
    {
        temp = huffCodes [ ByteToInt(std::to_string(b)) ];
        output.append(temp);
    }

显然这不是真实的代码,但是理想情况下,当我从huffCodes向量中收集所有字符串时,我将填充输出位集。是否可以通过某种串联或将字符串附加到位集中来做到这一点?

注意:huffCodes向量的内容是最大为8的字符串,仅由1和0组成。

1 个答案:

答案 0 :(得分:0)

您的瓶颈几乎可以肯定是这一行:

compressed += huffCodes [ ByteToInt(std::to_string(b)) ];

因为在循环遍历循环时,输出字符串(compressed)将被重新分配并复制多次。

代替这样做,请尝试以下操作。注意,这会预先分配一个适当大小的向量,以避免需要进行昂贵的重新分配和复制。我也看不到需要将b转换为字符串然后再转换回int的需要,所以我将其删除了:

std::string s;
int nbytes = 0;
for (b : bytes)
    nbytes += huffcodes [b].size ();

{
    std::vector <char> v (nbytes + 1);
    for (b : bytes)
    {
        auto hc = huffcodes [b];
        for (auto c : hc)
            v.push_back (c);
    }

    v.push_back (0);    // NUL terminator
    s = v.data ();
}

auto output = boost::dynamic_bitset<unsigned char> (s);

如您所见,转换为字符串是通过单个操作完成的。必须复制这么大的数据结构,但是似乎没有其他方法,这真是令人遗憾。