不幸的是,从C ++ 14开始,C ++标准库中没有动态尺寸矩阵类。矩阵类,支持动态大小但是可从许多的3个方程式库,其中包括升压矩阵库(Boost库中的子库)。
如果您不希望依赖Boost或其他库,那么C ++中一个穷人的动态大小矩阵就像
vector<vector<int>> m( 3, vector<int>( 7 ) );
...这里vector是std::vector。在这里,矩阵是通过将行向量复制n次而创建的,其中n是行数,这里是3。它的优点是提供与m[y][x]固定大小的原始数组矩阵相同的索引符号,但是效率不高,因为它涉及动态分配每一行,这有点不安全,因为可能会无意中调整行的大小。
一种更安全有效的方法是使用单个向量作为矩阵的存储,并将客户代码(x,y)映射到该向量中的相应索引:
// 使用std :: vector进行存储的动态大小矩阵。 //---------------------------------------------机械: #include <algorithm> // std :: copy #include <assert.h> // 断言 #include <initializer_list> // std :: initializer_list #include <vector> // std :: vector #include <stddef.h> // ptrdiff_t namespace my { using Size = ptrdiff_t; using std::initializer_list; using std::vector; template< class Item > class Matrix { private: vector<Item> items_; Size n_cols_; auto index_for( Size const x, Size const y ) const -> Size { return y*n_cols_ + x; } public: auto n_rows() const -> Size { return items_.size()/n_cols_; } auto n_cols() const -> Size { return n_cols_; } auto item( Size const x, Size const y ) -> Item& { return items_[index_for(x, y)]; } auto item( Size const x, Size const y ) const -> Item const& { return items_[index_for(x, y)]; } Matrix(): n_cols_( 0 ) {} Matrix( Size const n_cols, Size const n_rows ) : items_( n_cols*n_rows ) , n_cols_( n_cols ) {} Matrix( initializer_list< initializer_list<Item> > const& values ) : items_() , n_cols_( values.size() == 0? 0 : values.begin()->size() ) { for( auto const& row : values ) { assert( Size( row.size() ) == n_cols_ ); items_.insert( items_.end(), row.begin(), row.end() ); } } }; } // 我的命名空间 //---------------------------------------------用法: using my::Matrix; auto some_matrix() -> Matrix<int> { return { { 1, 2, 3, 4, 5, 6, 7 }, { 8, 9, 10, 11, 12, 13, 14 }, { 15, 16, 17, 18, 19, 20, 21 } }; } #include <iostream> #include <iomanip> using namespace std; auto main() -> int { Matrix<int> const m = some_matrix(); assert( m.n_cols() == 7 ); assert( m.n_rows() == 3 ); for( int y = 0, y_end = m.n_rows(); y < y_end; ++y ) { for( int x = 0, x_end = m.n_cols(); x < x_end; ++x ) { cout << setw( 4 ) << m.item( x, y ); // ←注意:不是`m [y] [x]`! } cout << '\n'; } }
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
上面的代码不是工业级的:它旨在显示基本原理,并满足学习C ++的学生的需求。
例如,可以定义operator()重载以简化索引符号。