C ++ Código Header Huffman
-
20-08-2019 - |
Pergunta
Basicamente, eu tenho minha mesa Huffman como
std::map<std::string, char> ciMap;
Onde string é o padrão de bits e char é o valor representado pelo referido padrão. O problema é como faço para armazenar que como um cabeçalho do meu arquivo compactado para que eu possa construir novamente o mesmo mapa quando eu quero decodificá-lo?
Tentando armazená-lo como binário:
size_t mapLen = ciMap.size();
outFile.write(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
outFile.write(reinterpret_cast<char*>(&ciMap), sizeof(ciMap));
E mais tarde edifício com:
inFile.read(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
inFile.read(reinterpret_cast<char*>(&ciMap), sizeof(mapLen));
não funciona, eu recebo string de erro initilization ... algo a ver com NULL. Alguma sugestão? Se você tiver a melhor maneira de armazenar os bits e valores que eu gostaria de ouvir.
Solução
Você pode fazê-lo sozinho, ou você pode fazê-lo com impulso: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html . O que você atualmente tentar é apenas ver o mapa como um tipo de dados velha lisa, o que essencialmente significa que é um tipo de dados C. Mas não é, por isso, ele não consegue salvar carga /. boost serialização faz isso corretamente. Ter um olhar para ele. Se você não quiser usá-lo, você pode fazer algo como isto:
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-se que as necessidades acima algumas mudanças se os caracteres armazenados poderia ser espaço em branco caracteres também. Por isso, é provavelmente o melhor para primeiro convertido para um int antes de escrever para fora, e depois de ler como um int ao carregar. Na verdade, eu recomendo impulso serialização e impulso iostreams ( http :. //www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html ), que inclui um fluxo de compressão de forma transparente que pode comprimir os seus dados também
Outras dicas
Você pode não só seriar os valores binários para o disco dessa maneira. A representação na memória não é simplesmente um bloco contíguo de memória, e mesmo que fosse ele provavelmente vai conter ponteiros que são relativas ao endereço do bloco.
Você precisa interagir sobre o mapa e serialize a cada item individualmente. Em seguida, trazê-los de volta em você reconstruir o mapa através da leitura dos itens fora um disco por um e reinserindo-os no mapa.
Ótima pergunta. Problema aqui é que os recipientes padrão não suportam serialização -. Você tem que escrevê-lo sozinho, é uma dor, mas é possível
Veja como você pode serializar um std::map
para um formato textual. Você pode adaptá-lo para escrever para qualquer formato binário que você precisa. Basta substituir o operador <<
com reads
e writes
.
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;
}