我有一个动态的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
您有什么想法?
答案 0 :(得分:0)
我首先想到的是您的程序已经完成很长时间了,而我的回答为时已晚。
但是,也许其他SO用户也想听听可能的解决方案。
读到您正在使用
std :: vector中以行为主的形式
建议使用std::valarray
。使用std::slice
(或其他类型的切片),您可以简单地对可以想象的所有索引进行操作。索引运算符[]
与slice一起仅在需要时才计算inde。那是非常强大且快速的。
用于构建矩阵的标准C ++方法是使用类型为std::vector
的{{1}}。然后访问该数据或对其进行操作。请注意:std::vector
也使用连续内存。您可以不同地访问它。例如:行很容易访问。您可以只使用第一个维度。对于std::vector<std::vector<int>>
,您只需编写std::vector<std::vector<int>> data;
即可访问该行中的所有列。
使用列会更困难。我的猜测是您想以某种方式实现对列的访问。否则,将无需计算列索引或列顺序的索引。
这样做的缺点是您不能将矩阵与data[row]
库一起使用。没有迭代器可用,嗯,很难。
我可以为您提供一个矩阵的解决方案,该矩阵具有行和列的迭代器。为此,我们使用了按列对algorithm
中正确值的引用向量。然后,我们可以遍历行和列并使用std::vector<std::vector<int>> data;
。
为了优化速度,可以在需要时创建列引用。这样可以减少构造函数的复杂性。
对于您的副节点:在构造函数中重复的代码。请在您的类中创建一个私有函数,然后在构造函数中调用它。
请查看带有一些测试代码(MSVS19)的矩阵的骨架:
std::algorithm
希望这对如何工作提供了一个思路