сжатая длина строки с помощью boost :: iostreams

У меня есть строка (некоторой фиксированной длины), которую мне нужно сжать, а затем сравнить сжатые длины (как прокси для избыточности в данных или как грубое приближение к колмогоровской сложности). В настоящее время я использую boost :: iostreams для сжатия, который, кажется, работает хорошо. Тем не менее, я не знаю, как получить размер сжатых данных. Может кто-нибудь помочь, пожалуйста?

Фрагмент кода

#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/filesystem.hpp>
#include <string>
#include <sstream>

namespace io = boost::iostreams;

int main() {

std::string memblock;

std::cout << "Input the string to be compressed:";
std::cin >> memblock;

std::cout << memblock << std::endl;

io::filtering_ostream out;
out.push(io::gzip_compressor());
out.push(io::file_descriptor_sink("test.gz"));
out.write (memblock.c_str(), memblock.size());

std::cout << out.size() << std::endl;

return 0;

}

2

Решение

Вы можете попробовать добавить boost::iostreams::counter вам цепь между компрессором и раковиной, а затем называя это characters() член, чтобы получить количество байтов, которые прошли через него.

Это работает для меня:

#include <boost/iostreams/filter/counter.hpp>

io::filtering_ostream out;
out.push(io::counter());
out.push(io::gzip_compressor());
out.push(io::counter());
out.push(io::file_descriptor_sink("test.gz"));
out.write (memblock.c_str(), memblock.size());
io::close(out); // Needed for flushing the data from compressor

std::cout << "Wrote " << out.component<io::counter>(0)->characters() << " bytes to compressor, "<< "got " << out.component<io::counter>(2)->characters() << " bytes out of it." << std::endl;
5

Другие решения

Я нашел еще один (и немного более приятный) способ достижения сжатой длины строки. Я думал поделиться этим здесь, но в основном это просто передача несжатой строки в отфильтрованный буфер и копирование вывода обратно в строку:

template<typename T>
inline std::string compressIt(std::vector<T> s){

std::stringstream uncompressed, compressed;
for (typename std::vector<T>::iterator it = s.begin();
it != s.end(); it++)
uncompressed << *it;

io::filtering_streambuf<io::input> o;
o.push(io::gzip_compressor());
o.push(uncompressed);
io::copy(o, compressed);

return compressed.str();
}

Позже можно легко получить размер сжатой строки как

compressIt(uncompressedString).size()

Я чувствую, что это лучше, потому что не требуется, чтобы я создал выходной файл, как ранее.

веселит,
Нихилу

1

один другой способ будет

stream<array_source> input_stream(input_data,input_data_ize);
stream<array_sink> compressed_stream(compressed_data,alloc_compressed_size);
filtering_istreambuf out;
out.push(gzip_compressor());
out.push(input_stream);
int compressed_size = copy(out,compressed_stream);
cout << "size of compressed_stream" << compressed_size << endl;
0
По вопросам рекламы [email protected]