여기 행수가 semi_dynamic_matrix::insert_row
, semi_dynamic_matrix::erase_row
, semi_dynamic_matrix::pop_row
와 semi_dynamic_matrix::rows_resize
하여 실행 시간에 변경 될 수있는 로우 - 주요 구성 하부 컨테이너 유형으로 std::vector
를 사용하여 구현 가능하다. 이 클래스에 대한 작업을 전형적인 <algorithm>
헤더 (등)을 수행 할 수 있습니다 있도록
template<typename Ty,
class Allocator = std::allocator<Ty>
> class semi_dynamic_matrix {
class proxy_row_vector { // use to allow [][] usage on semi_dynamic_matrix objects
public:
proxy_row_vector(std::vector<Ty, Allocator>& _vec, std::size_t i, std::size_t cols)
: vec(_vec), row_ind(i), cols_(cols) {}
const Ty& operator[](std::size_t j) const {
return vec[row_ind*cols+j];
}
Ty& operator[](std::size_t j) {
return vec[row_ind*cols+j];
}
private:
std::vector<Ty, Allocator>& vec;
std::size_t row_ind;
std::size_t cols_;
};
public:
// PUBLIC TYPEDEFS
typedef Ty value_type;
typedef Ty& reference;
typedef const Ty& const_reference;
typedef Ty* pointer;
typedef const Ty* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef Allocator allocator_type;
typedef typename std::vector<Ty,Allocator>::iterator iterator;
// and similar for const_iterator, reverse_iterator...
// CONSTRUCTION/ASSIGNMENT
// default constructor
semi_dynamic_matrix() : semi_dynamic_matrix(Allocator()) {}
explicit semi_dynamic_matrix(const Allocator& alloc)
: mtx(alloc), rows_(0U), cols_(0U) {}
// construct matrix of size rows*cols
explicit semi_dynamic_matrix(size_type rows, size_type cols, const Allocator& alloc = Allocator())
: mtx(rows*cols, alloc), rows_(rows), cols_(cols) {}
// other constructors (copy, move, ...)
// CAPACITY
size_type rows() const noexcept { return rows_; }
constexpr size_type columns() const noexcept { return cols_; }
// ELEMENT ACCESS
proxy_row_vector operator[](size_type i) const {
return proxy_row_vector(mtx, i, cols_);
}
proxy_row_vector operator[](size_type i) {
return proxy_row_vector(mtx, i, cols_);
}
// other accessors, e.g. at(), front(), ...
// ITERATORS
iterator begin() noexcept { return mtx.begin(); }
iterator end() noexcept { return mtx.end(); }
// similarly for cbegin(), cend(), rbegin(), ...
// MODIFIERS
iterator insert_row(size_type row_pos, const value_type& val) {
return insert_row(row_pos, std::vector<value_type>(cols_, val));
}
iterator insert_row(size_type row_pos, const std::vector<value_type>& row_vec) {
if (row_pos > rows_) throw std::out_of_range("message");
if (row_vec.size() != cols_) throw std::invalid_argument("message");
++rows_;
return mtx.insert(mtx.begin()+row_pos*cols_, row_vec.begin(), row_vec.end());
}
iterator insert_row(size_type row_pos, std::vector<value_type>&& row_vec =
std::vector<value_type>()) {
if (row_pos > rows_) throw std::out_of_range("message");
if (row_vec.size() > cols_) throw std::invalid_argument("message");
++rows_;
if (row_vec.size() < cols_) row_vec.resize(cols_);
return mtx.insert(mtx.begin()+row_pos*cols_, std::make_move_iterator(
row_vec.begin()), std::make_move_iterator(row_vec.end()));
}
iterator erase_row(size_type row_pos) {
if (!(row_pos < rows_)) throw std::out_of_range("");
--rows_;
return mtx.erase(mtx.begin()+row_pos*cols_, mtx.begin()+cols_*(row_pos+1));
}
void pop_row() {
for (size_type i = 0; i < cols_; ++i) mtx.pop_back();
--rows_;
}
void rows_resize(size_type rows) {
size_type tmp_rows = rows_;
if (rows == rows_) return;
if (rows > rows_) { // expand
for (size_type i = 0; i < (rows_-tmp_rows); ++i)
insert_row(rows_, std::move(std::vector<value_type>(cols_)));
}
else { // contract
for (size_type i = 0; i < (tmp_rows-rows); ++i) pop_row();
}
}
private:
std::vector<value_type, allocator_type> mtx;
size_type rows_;
size_type cols_;
};
은 그럼 당신은
semi_dynamic_matrix<int> sdm(3,3); // create matrix of size 3x3
sdm.rows_resize(5); // resize matrix to 5x3
sdm.erase_row(0); // erase first row of matrix, size is now 4x3
가 기본이 반복자 타입 그냥 std::vector
반복자를 사용하므로 같은이를 사용할 수 있습니다.
또는 행과 열 모두에서 동적 인 행렬 구조를 원한다면 잠시 전에 작성한 구현을 사용해보십시오 (dynamic_matrix
).
벡터 데이터는 항상 연속입니다. – amchacon
@amchacon 벡터가 연속이라는 것을 알게되지만 std :: array를 저장하면 std :: array 클래스 래퍼도 저장되므로 전체 데이터가 연속적이지는 않습니다. –
'std :: array'에 대한 클래스 래퍼는 실질적으로 아무것도 없거나'std :: array>'연속하지 않을 것입니다. –
user4581301