2012-06-27 175 views
2

我使用來自stl的bitset或來自boost的dynamic_bitset <>(我可以使用任何我想要的)代表位圖(矩陣行x列)。我需要得到尺寸較小的矩陣的子矩陣(例如 a(2,2)a(2,3)a(3,2)a(3,3)的大小爲2)。有沒有任何有效的結構來表示矩陣的位,並獲得從startindex和長度的子矩陣,沒有迭代?獲取更小尺寸的矩陣的子矩陣

+0

與提升範圍和切片相同的概念。不確定確切的實施。 –

回答

2

在矩陣和子矩陣之間有效地共享數據是可能的。訣竅是跟蹤你班上的三個變量。

  • row_stride
  • 開始
  • 數據

data需要是shared_ptr狀結構,使基礎數據的,一旦你用它做被破壞。 start將是一個指向data,row_stride引用的數據的指針,告訴你要走多遠到達下一行。

你可能想追蹤其他事情

  • 柱跨度(這可以讓你把其他有趣的觀點到矩陣,並支持高效轉)。
  • 行和列的長度 - 這些可以方便地進行調試,或者如果你想讓你的循環,並乘以更容易處理。

下面是如何尋找一個非基於位的方法(我已經省略了很多..但希望你能得到要點)。

template<typename T> 
struct MatrixData 
{ 
    T * data; 
    explicit MatrixData(size_t N) { new T[N]; } 
    ~MatrixData() { delete [] data; } 
private: 
    MatrixData(const MatrixData &); 
    MatrixData& operator=(const MatrixData &); 
}; 

template<typename T> 
class Matrix 
{ 
    Matrix(size_t nni, size_t nnj) : 
     data(new MatrixData(nni*nnj)), 
     ni(nni), 
     nj(nnj), 
     row_stride(ni), 
     col_stride(1) 
    { 
    } 

    T operator()(size_t i, size_t j) 
    { 
     assert(i < ni); 
     assert(j < nj); 
     return start + i * col_stride + j * row_stride; 
    } 

    Matrix submatrix(size_t i_start, size_t j_start, size_t new_ni, size_t new_nj) 
    { 
     assert(i_start + new_ni < ni); 
     assert(j_start + new_nj < nj); 

     Matrix retval(*this); 
     retval.start += i_start * col_stride + j_start * row_stride; 
     retval.ni = new_ni; 
     retval.nj = new_nj; 
     return retval; 
    } 

    Matrix transpose() 
    { 
     Matrix retval(*this); 
     std::swap(retval.ni,retval.nj); 
     std::swap(retval.row_stride,retval.col_stride); 
    } 

    private: 
    shared_ptr<MatrixData> data; 
    T* start; 
    size_t ni; 
    size_t nj; 
    size_t row_stride; 
    size_t col_stride; 

}; 

使這項工作對基於位版本將意味着改變MatrixData舉行BOT基礎結構之一,改變start是一種索引結構,改變你的operator()正確地訪問數據。