我正在实现一个使用霍夫曼编码来压缩文件的程序。我在将压缩字符串的位写入另一个位集时遇到麻烦。我有一个字节向量(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组成。
答案 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);
如您所见,转换为字符串是通过单个操作完成的。必须复制这么大的数据结构,但是似乎没有其他方法,这真是令人遗憾。