简体   繁体   English

C ++霍夫曼代码头

[英]C++ Huffman Code Header

basically, I've got my Huffman table as 基本上,我有我的霍夫曼表

std::map<std::string, char> ciMap;

Where string is the bit pattern and char is the value represented by said pattern. 其中string是位模式,char是由所述模式表示的值。 The problem is how do I store that as a header of my compressed file so I can build again the same map when I want to decode it? 问题是如何将其存储为我的压缩文件的标题,以便在我想要解码时再次构建相同的地图?

Trying to store it as binary: 试图将其存储为二进制文件:

size_t mapLen = ciMap.size();
outFile.write(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
outFile.write(reinterpret_cast<char*>(&ciMap), sizeof(ciMap));

And later building with: 后来建设:

inFile.read(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
inFile.read(reinterpret_cast<char*>(&ciMap), sizeof(mapLen));

Doesn't work, I get string initilization error... something to do with NULL. 不起作用,我得到字符串初始化错误...与NULL有关。 Any suggestions? 有什么建议么? If you have better way of storing the bits and values I'd like to hear. 如果您有更好的方法来存储我想听到的位和值。

You can do it yourself, or you can do it with boost: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html . 你可以自己动手,也可以通过提升来实现: http//www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html What you currently try is just view the map as a plain old datatype, which essentially means it's a C datatype. 您目前尝试的只是将地图视为普通的旧数据类型,这实质上意味着它是一种C数据类型。 But it isn't, so it fails to save/load. 但事实并非如此,因此无法保存/加载。 boost serialization does it correctly. boost序列化正确完成。 Have a look at it. 看看它。 If you don't want to use it, you can do something like this: 如果您不想使用它,您可以执行以下操作:

typedef std::map<std::string, char> my_map;
my_map ciMap;

// saving
std::ofstream stream("file.txt");
for(my_map::const_iterator it = ciMap.begin(); it != ciMap.end(); ++it) {
    stream << it->first << " " << it->second << std::endl;
}

// loading
char c;
std::string bits;
std::ifstream stream("file.txt");
while(stream >> bits >> c)
    ciMap.insert(std::make_pair(bits, c));

Note that the above needs some changes if the characters stored could be whitespace characters too. 请注意,如果存储的字符也可能是空白字符,则上述操作需要进行一些更改。 Because of that, it's probably the best to first convert to an int before writing out, and then reading as an int when loading. 因此,在写出之前首先转换为int,然后在加载时作为int读取可能是最好的。 Actually, i recommend boost serialization, and boost iostreams ( http://www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html ), which includes a compression stream that transparently can compress your data too. 实际上,我建议使用boost序列化和增强iostreams( http://www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html ),其中包括一个透明地压缩数据的压缩流。

You can't just serialize the binary values to disk in this way. 您不能以这种方式将二进制值序列化到磁盘。 The in memory representation is not simply a contiguous block of memory, and even if it was it will likely contain pointers which are relative to the address of the block. 内存表示不仅仅是一个连续的内存块,即使它可能包含相对于块地址的指针。

You need to iterate over the map and serialize out each item individually. 您需要迭代地图并单独序列化每个项目。 Then to bring them back in you reconstruct the map by reading the items off disk one by one and reinserting them into the map. 然后将它们带回来通过逐个读取磁盘上的项目并将它们重新插入到地图中来重建地图。

Great question. 好问题。 Problem here is that the default containers don't support serialization - you have to write it yourself, it's a pain, but it's possible. 这里的问题是默认容器不支持序列化 - 你必须自己编写,这很痛苦,但它是可能的。

Here's how you could serialize a std::map to a textual format. 以下是将std::map序列化为文本格式的方法。 You can adapt it to write to whatever binary format you need. 您可以调整它以写入您需要的任何二进制格式。 Just replace the << operator with reads and writes . 只需更换<<操作员readswrites

template<typename K, typename V>
std::ostream &operator << (std::ostream &out, const std::map<K,V> &map) {
    out << "map " << map.size() << "\n";
    for (typename std::map<K,V>::const_iterator i = map.begin(); i != map.end(); ++i) {
        out << (*i).first << "\n" << (*i).second << "\n";
    }
    return out;
}

template<typename K, typename V>
std::istream &operator >> (std::istream &in, std::map<K,V> &map) {
    std::string mapkeyword;
    size_t num;
    in >> mapkeyword >> num;
    for (size_t i = 0; i < num; ++i) {
        K key; V value;
        in >> key >> value;
        map[key] = value;
    }
    return in;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM