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)

random_small.core (10.0 KB) - added by Дмитрий Свиридкин 4 years ago.

Download all attachments as: .zip

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: ожидается проверкаожидаются исправления

Работает некорректно: на приложенном файле результат архивирования - разархивирования не совпадает с исходным файлом.

Путей к заголовкам вида ../XXX быть не должно. Используйте флаг -I.

Код построения дерева (заполнение priority_queue) должен быть внутри класса HuffmanTree?. Он дублируется в тестах и в функции Huffman::encode.

comment:2 Changed 4 years ago by sunko.elena

Owner: changed from sunko.elena to Дмитрий Свиридкин
Type: ожидаются исправленияожидается проверка
Version: 1.02.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

Last edited 4 years ago by Дмитрий Свиридкин (previous) (diff)

comment:4 Changed 4 years ago by sunko.elena

Owner: changed from sunko.elena to Дмитрий Свиридкин
Type: ожидаются исправленияожидается проверка
Version: 2.03.0

comment:5 Changed 4 years ago by Дмитрий Свиридкин

Resolution: задача сдана
Status: assignedclosed

*

 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

Note: See TracTickets for help on using tickets.