Skip to content

Instantly share code, notes, and snippets.

@alzobnin
Last active March 9, 2021 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alzobnin/382343905a08dabc93e512a9b0bd4c50 to your computer and use it in GitHub Desktop.
Save alzobnin/382343905a08dabc93e512a9b0bd4c50 to your computer and use it in GitHub Desktop.

Разбор задачи «Таблица»

Условие

Вам надо написать шаблонный класс Table для электронной таблицы. Для простоты будем считать, что все ячейки таблицы имеют один и тот же тип данных T. Таблица должна уметь менять свой размер по требованию пользователя. Вновь созданные ячейки должны заполняться значениями по умолчанию типа T.

Требования к классу такие:

  1. Класс должен называться Table.
  2. У класса должен быть шаблонный параметр T — тип элемента в ячейке.
  3. У класса должен быть конструктор, получающий на входе два числа типа size_t, — начальные размеры таблицы.
  4. У класса должны быть константная и неконстантная версии оператора [], возвращающего нечто такое, к чему снова можно было бы применить оператор []. То есть, должны работать конструкции вида std::cout << table[i][j]; и table[i][j] = value;. Проверять корректность индексов при этом не нужно.
  5. У класса должна быть функция resize, получающая на вход два параметра типа size_t и меняющая размер таблицы. Старые данные, умещающиеся в новый размер, должны при этом сохраниться.
  6. У класса должна быть функция size, возвращающая std::pair<size_t, size_t> — размер таблицы (в том же порядке, в котором эти аргументы передавались в конструктор).

Решение

#include <vector>
#include <utility>

template <typename T>
class Table {
private:
    std::vector<std::vector<T>> data;

public:
    Table(size_t m, size_t n) {
        resize(m, n);
    }

    // версия для неконстантных таблиц
    std::vector<T>& operator[] (size_t i) {
        return data[i];
    }

    // версия для константных таблиц
    const std::vector<T>& operator[] (size_t i) const {
        return data[i];
    }

    void resize(size_t m, size_t n) {
        data.resize(m);
        for (size_t i = 0; i < m; ++i) {
            data[i].resize(n);
        }
    }

    std::pair<size_t, size_t> size() const {
        if (data.empty()) {
            return {0, 0};
        } else {
            return {data.size(), data[0].size()};
        }
    }
};

Часто задаваемый вопрос - какой индекс в таблице отвечает за строки, а какой - за столбцы. На самом деле это совершенно не важно. Главное, чтобы пара индексов i и j, по которым будут обращаться в таблицу, была бы согласованной с размерами: i должен быть меньше m, а j меньше n.

Другая типичная ошибка - возврат {data.size(), data[0].size()} в функции size() без проверки пустоты вектора. На пустом data тут будет некорректное обращение к памяти в data[0].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment