Opened 4 years ago
Closed 4 years ago
#925 closed ожидается проверка (задача сдана)
HW #3
Reported by: | sunko.elena | Owned by: | Дмитрий Свиридкин |
---|---|---|---|
Component: | HW #3 (Huffman) | Version: | 3.0 |
Keywords: | Cc: |
Description
Attachments (1)
Change History (6)
Changed 4 years ago by
Attachment: | random_small.core added |
---|
comment:1 Changed 4 years ago by
Owner: | changed from Дмитрий Свиридкин to sunko.elena |
---|---|
Type: | ожидается проверка → ожидаются исправления |
comment:2 Changed 4 years ago by
Owner: | changed from sunko.elena to Дмитрий Свиридкин |
---|---|
Type: | ожидаются исправления → ожидается проверка |
Version: | 1.0 → 2.0 |
comment:3 Changed 4 years ago by
Owner: | changed from Дмитрий Свиридкин to sunko.elena |
---|---|
Type: | ожидается проверка → ожидаются исправления |
Test failed -- expected compressed data to be no longer than source data, got 5 > 3
сжатые данные из файла со строчкой "abc" (именно сами биты, без вспомогательной информации, а не итоговый файл) точно можно уместить в один байт вместо пяти (5 -- из лога).
std::ifstream source; source.open(args.source_file, std::ios::binary); std::ofstream destination; destination.open(args.destination_file, std::ios::binary);
Открывайте сразу конструктором. Не надо разрывать объявление и инициализацию
Вызывать close() также не надо. RAII это хорошо.
#include <unistd.h>
Вот давайте без платформозависимых заголовков. Если сильно нужно, то https://en.cppreference.com/w/cpp/filesystem/exists
extract_flag/compress_flag в структуре command_arguments
лучше заменить на enum с тремя значениями.
#include <bits/exception.h>
каталог bits -- это внутренности специфичные для gcc. Вам нужен <exception>
или <stdexcept>
virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT
Где вы эти макросы откопали? Просто noexcept
static void get_code_for_each_symbol(HuffmanNode* node, const std::string& code, std::map<char, std::string>& code_table);
Странно, что функция с именем get ничего не возвращает. Возвращайте результат через возвращаемое значение, а не через аргумент.
Расставьте const там, где это уместно.
Очень неэффективно добавлять к строке с каждым битом новый символ и кажды раз после этого искать в std::map. Раскодирование с помощью дерева намного эффективнее: обрабатывайте деревом по одному биту -- как только дошли до листа -> забирайте байт.
std::size_t HuffmanArchiver::save(std::istream &in, std::ostream& out) { in.seekg(0, std::ios::beg);
Функция не должна знать, что поток не перемотан.
Его должен был перемотать на начало вызывающий код. А еще лучше -- та функция, которая его пред этим читала. Гарантируйте инвариант: перед и после вызова каждого I/O метода поток перемотан в начало.
Построение priority_queue должно быть в приватных методах дерева. Конструктор дерева принимает только таблицу частот. Все остальное -- нужно инкапсулировать.
Huffman encoder; size_of_initial_data_bytes = BinaryFileReader::size_of_istream_bytes(in); for (std::size_t i = 0; i < size_of_initial_data_bytes; i++) { encoder.add_to_frequency_table(BinaryFileReader::get_byte(in)); } frequency_table = encoder.get_frequency_table();
Почему бы вот это все добро не сделать одной законченной функцией, принимающей поток и возвращающей таблицу со статистикой символов?
Можно сделать класс-обертку BitWriter? и спрятать в него всю страшную логику с анализом, закончился ли очередной байт. Аналогично BitReader?
Для таблицы кодов/частот стоит сделать свою структуру (оборачивающую std::map/std::vector) с методами Read/Write?.
5 + 6 (эффективность сжатия?) + 3 + 6.5
comment:4 Changed 4 years ago by
Owner: | changed from sunko.elena to Дмитрий Свиридкин |
---|---|
Type: | ожидаются исправления → ожидается проверка |
Version: | 2.0 → 3.0 |
comment:5 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
*
if (args.compress_flag != ARGUMENT_NOT_SET) { archiver.compress(source, destination); } if (args.extract_flag != ARGUMENT_NOT_SET) { archiver.extract(source, destination); }
Это взаимоисключающие действия. Лучше сделать одно поле action_type
, принимающее значения из enum (2 или 3 элемента : COMPRESS, DECOMPRESS, NONE)
*
std::cout << archiver.get_size_of_initial_data() << std::endl; std::cout << archiver.get_size_of_processed_data() << std::endl; std::cout << archiver.get_size_of_ancillary_data() << std::endl;
Эти значения можно вернуть из функций compress/extract, чтобы не хранить их в качестве состояния архиватора.
*
void set_size_of_initial_data(std::size_t new_size); void set_table_symbol_code(std::map<char, std::string>& new_table); void set_encoded_data_string_size(int32_t new_size); void set_table_code_symbol(std::map<std::string, char>& new_table); std::size_t save(std::istream& in, std::ostream& out); void decode(std::istream& in, std::ostream& out);
void create_nodes_queue(std::map<char, uint64_t> &frequency_table, std::priority_queue<HuffmanNode*, std::vector<HuffmanNode*>, HuffmanNode::compare_nodes>& nodes_queue); void build_tree(std::priority_queue<HuffmanNode*, std::vector<HuffmanNode*>, HuffmanNode::compare_nodes>& nodes_queue);
Эти методы не должны быть частью публичных интерфейсов.
9 + 8 + 4 + 7.5
Работает некорректно: на приложенном файле результат архивирования - разархивирования не совпадает с исходным файлом.
Путей к заголовкам вида
../XXX
быть не должно. Используйте флаг -I.Код построения дерева (заполнение priority_queue) должен быть внутри класса HuffmanTree?. Он дублируется в тестах и в функции Huffman::encode.