У меня есть динамический шаблонный класс Matrix
, для которого я хочу создать вектор и заполнить его индексами, которые идут вниз по столбцам, а не по строкам.Как вы, наверное, уже догадались из того, что я только что сказал, я храню фактические данные матрицы в виде строки-строки в std::vector<T>
.Вот упрощенная версия моего определения класса Matrix только с соответствующими частями.
template<typename T>
class Matrix {
public:
Matrix(std::size_t m, std::size_t n, const T &elem = T());
Matrix(const std::vector<T> &vec, std::size_t m, std::size_t n);
Matrix(std::initializer_list<T> list, std::size_t m, std::size_t n);
private:
typedef std::vector<std::size_t> reindex_scheme;
std::vector<T> _data;
reindex_scheme _colindices;
std::size_t _m;
std::size_t _n;
};
По сути, я хочу, чтобы, когда мне был предоставлен этот фрагмент кода:
std::vector<int> input {1, 2, 4, 6, 5, 4};
Matrix<int> A(input, 2, 3); // creates a 2x3 matrix with entries 1 2 4
// 6 5 4
для того, чтобы сохранить следующее в _colindices
в следующем порядке:
0 3 1 4 2 5
(если вы поймете, что я делаю, я просто беру индекс элемента, если вы пересекаете матрицу следующим образом:
| /| /|
| / | / |
\/ \/ \/
надеюсь, вы сможете разобраться со стрелками)
То, что у меня пока есть для конструкторов, - это «наивный» for
метод на основе:
template<typename T>
Matrix<T>::Matrix(std::size_t m, std::size_t n, const T &elem)
: _data(m * n, elem),
_colindices(m * n),
_m(m),
_n(n) {
for (std::size_t i = 0; i < _n; i++)
for (std::size_t j = 0; j < _m; j++)
_colindices[i * _m + j] = j * _n + i;
}
template<typename T>
Matrix<T>::Matrix(const std::vector<T> &vec, std::size_t m, std::size_t n)
: _data(vec),
_colindices(m * n),
_m(m),
_n(n) {
for (std::size_t i = 0; i < _n; i++)
for (std::size_t j = 0; j < _m; j++)
_colindices[i * _m + j] = j * _n + i;
}
template<typename T>
Matrix<T>::Matrix(std::initializer_list<T> list, std::size_t m, std::size_t n)
: _data(list),
_colindices(m * n),
_m(m),
_n(n) {
for (std::size_t i = 0; i < _n; i++)
for (std::size_t j = 0; j < _m; j++)
_colindices[i * _m + j] = j * _n + i;
}
Кроме того, в качестве примечания вы можете увидеть глупое дублирование кода, которое я делаю для трех конструкторов.Если вы знаете, как лучше объединить три в один или, по крайней мере, три в два, пожалуйста, сообщите мне и здесь. (извините, это стало своего рода двойным вопросом)
Это for
метод работает, но, очевидно, это O (mn), и мне нравится думать, что есть лучший, более эффективный способ, может быть, с некоторыми std
методами?Я думал о чем-то вроде создания вектора с 0 3
, а затем итерации по нему, создания нового вектора путем увеличения каждого элемента, может быть, на std::transform
или чего-то еще, и добавления этого в конец конечного вектора, пока я не доберусь доконец (если вы понимаете, о чем я говорю).Вроде как
Loop Iteration 1:
0 3
Loop Iteration 2:
0 3 1 4
Loop Iteration 3:
0 3 1 4 2 5
Что ты думаешь?