我有一个std::vector
std::vectors
我希望使用for循环将一个元素推回到每个内部向量。代码看起来像这样,但显然不起作用,因为你不能以这种方式访问每个向量(matrix[i] =
)而第8行产生Segmentation Fault
。
std::vector<std::vector<float> > matrix;
for (size_t j = 0; j < number_of_columns; ++j) {
vector<float> elements_to_push = compute_elements();
for (size_t i = 0; i < number_of_rows; ++i) {
matrix[i].push_back(elements_to_push[i]);
}
}
所以,我想按列编写元素。顺行写入不是我的选择,因为我需要使用一些期望元素按顺序排列的外部函数。
我认为解决方案涉及使用指针向量(std::vector<float*>
),但我想知道是否可以使用向量来实现它,因为这简化了事情。
此外,如果解决方案不涉及C ++ 11或更高版本的功能,那将是最好的,因为我必须保持向后兼容性。但是,如果你有一个使用C ++ 11或更高版本的答案,你仍然可以为任何可能发现它有用的人写它。
答案 0 :(得分:1)
如果计算并推送行而不是列,会更容易。但是这里有一个解决方案(因为你已经知道了矩阵的大小):
std::vector<std::vector<float> > matrix(number_of_rows, std::vector<float>(number_of_columns, float()));
for (size_t j = 0; j < number_of_columns; ++j) {
vector<float> elements_to_push = compute_elements();
for (size_t i = 0; i < number_of_rows; ++i) {
matrix[i][j] = elements_to_push[i];
}
}
答案 1 :(得分:1)
我建议在行主要配置中围绕单个std::vector
创建一个包装器来表示您的矩阵,使其比2D std::vector
更方便使用。以下应该与pre-c ++ 11兼容,这就是为什么我没有使用auto
和其他一些c ++ 11以上的功能......
template<typename Ty>
class matrix {
// enables use of [][] on matrix objects
class proxy_row_vector {
public:
proxy_row_vector(std::vector<Ty>& _vec, std::size_t cols, std::size_t row_ind)
: vec(_vec), columns(cols), row_index(row_ind) {}
const Ty& operator[](std::size_t col_ind) const {
return vec[row_index*columns + col_ind];
}
Ty& operator[](std::size_t col_ind) {
return vec[row_index*columns + col_ind];
}
private:
std::vector<Ty>& vec;
std::size_t row_index;
std::size_t columns;
};
public:
// construct rows*cols matrix with default-inserted Ty instances
explicit matrix(std::size_t rows, std::size_t cols)
: mtx(rows*cols), rows_(rows), cols_(cols) {}
std::size_t rows() const { return rows_; }
std::size_t columns() const { return cols_; }
// used for const [][] access
proxy_row_vector operator[](std::size_t row_ind) const {
return proxy_row_vector(mtx, cols_, row_ind);
}
// used for mutable [][] access
proxy_row_vector operator[](std::size_t row_ind) {
return proxy_row_vector(mtx, cols_, row_ind);
}
// insert a new row at the end
void push_row(const std::vector<Ty>& row_vec) {
for (std::vector<Ty>::iterator it = row_vec.begin(); it < row_vec.end(); ++it)
mtx.push_back(*it);
++rows_;
}
// insert a new column at the end
void push_column(const std::vector<Ty>& col_vec) {
insert_column(cols_, col_vec);
}
// insert a row at indicated position
void insert_row(size_type row_pos, const std::vector<Ty>& row_vec) {
mtx.insert(mtx.begin() + row_pos*cols_, row_vec.begin(), row_vec.end());
++rows_;
}
// insert a column at indicated position
void insert_column(size_type col_pos, const std::vector<Ty>& col_vec) {
for (std::size_t i = 0; i < col_vec.size(); ++i) {
mtx.insert(mtx.begin() + i*(cols_+1)+col_pos,col_vec[i]);
}
++cols_;
}
private:
std::vector<Ty> mtx;
std::size_t rows_;
std::size_t cols_;
};
然后使用您的示例推送新列很简单:
matrix<float> mat;
std::vector<float> column_to_push = compute_elements();
mat.push_column(column_to_push);
注意:在上面的matrix
类中没有边界或大小检查,因为它是这种类的最小示例。您应该在行/列插入方法中添加大小检查,以避免尝试推送分别超过(或低于)矩阵的当前列数或行数的行向量或列向量。另外,您可能希望添加迭代器支持(通过std::vector
迭代器)和其他方法(例如擦除行/列)。