使用 stdvector 進行儲存的動態大小矩陣
不幸的是,從 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 ) 對映到該向量中的相應索引:
// A dynamic size matrix using std::vector for storage.
//--------------------------------------------- Machinery:
#include <algorithm> // std::copy
#include <assert.h> // assert
#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()` );
}
}
};
} // namespace my
//--------------------------------------------- Usage:
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 ); // ← Note: not `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()
過載以簡化索引表示法。