2017-07-26 60 views
0
void Solution::rotate(vector<vector<int> > &A) { 
    int n= A.size(); 
int temp[n]; 
for(int j=0;j<n;j++) 
{ 
    temp[j]=A[n-1][j]; 
} 
    for(int i=0;i<n-1;i++) 
    { 
     A[n-1][i]=A[n-i-1][n-1]; 
     A[n-i-1][n-1] = A[0][n-i-1]; 
     A[0][n-i-1]=A[i][0]; 
     A[i][0]=temp[i]; 
     //A[i+1][0]=A[n-1][i+1]; 
    } 
} 

我想再次调用该函数并传递原始数组的子数组,起始点为数组的起点(1,1)和终点作为(n-2,n-2)阵列。 是否有可能在不创建新的矢量的情况下完成它,我的意思是通过传递一些指向该函数的指针?如何通过C++中的函数中的2d向量的子向量

+2

最简单的(和最快的,即优化)这样做是使用扁平'矢量'和从二维映射到一维和副的方式-versa。 – vsoftco

+1

如果要在两个维度上切片,只需传递每个维度的第一个和最后一个索引,然后使用它编辑通过引用*传递的矢量。 –

+0

通过限制尺寸作为参数与矢量应该完成工作。 – MASh

回答

0

如果您只想查看子矩阵或就地编辑有界区域,请创建查看器。观众不会做任何事情,只能限制您允许看的矩阵区域。没有复制和少量额外的内存使用。例如,如果您有一幅巨大的图片,并且您想查看和操作8x8的元素区域,这非常棒。

如果您需要给定视图的新矩阵,请教观看者根据视图创建一个新矩阵。在这种情况下涉及复制,但是当您想要复制时,复制很难避免。为了演示,首先我要稍微走开一段路径。如果你想这样做很快(谁不想快速?)不要使用vector<vector>。一个vector被保证在内存中是连续的,但是当你有矢量矢量保证走出窗口时,这会导致空间局部性差,并且通常导致缓存使用率低下。

下面是一个Matrix类的简单例子,它有点容易使用,并且都是一个内存块,因此它更容易缓存。

// wrapping class for 2D matrixes 
class Matrix 
{ 
private: 
    size_t rows, columns; // large, unsigned datatype. Don't want negative 
          // indices, so why allow them? 
    std::vector<int> matrix; // 1D vector. Simple and easy to handle. 
          // also often much faster than vector of vectors 
          // due to improved spatial locality helping 
          // predictability of data access 
public: 
    // build zero-filled Matrix 
    Matrix(size_t numrows, size_t numcols) : 
      rows(numrows), columns(numcols), matrix(rows * columns) 
    { 
    } 

    // 2D to 1D mapping accessor 
    int & operator()(size_t row, size_t column) 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    // 2D to 1D mapping accessor for constant Matrix 
    int operator()(size_t row, size_t column) const 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    // dimension accessors 
    size_t getRows() const 
    { 
     return rows; 
    } 
    size_t getColumns() const 
    { 
     return columns; 
    } 
}; 

现在,我们有一个更快,很好地包含Matrix类,我们可以做一个非常简单的MatrixView类。

class MatrixView 
{ 
    size_t mStartRow;  // view offset in row 
    size_t mStartColumn; // view offset in column 
    size_t mRows;   // number of viewed rows 
    size_t mColumns;  // number of viewed columns 
    Matrix & mMat;   // viewed Matrix 

public: 
    // using start and endpoints in this constructor. A more ideologically correct 
    // constructor would behave the same as the standard library and take offset 
    // and length as parameters. 
    MatrixView(size_t startrow, 
       size_t startcolumn, 
       size_t endrow, 
       size_t endcolumn, 
       Matrix & mat): 
        mStartRow(startrow), 
        mStartColumn(startcolumn), 
        mRows(endrow - startrow), 
        mColumns(endcolumn - startcolumn), 
        mMat(mat) 
    { 
     //ensure dimensions make sense 
     if (startrow > endrow || 
      startcolumn > endcolumn || 
      mRows > mat.getRows() || 
      mColumns > mat.getColumns()) 
     { 
      throw std::runtime_error("Bad MatrixView dimensions"); 
     } 
    } 
    int & operator()(size_t row, size_t column) 
    { 
     // check bounds here if you want to 
     // look at the source matrix plus offsets 
     return mMat(row+mStartRow, column+mStartColumn); 
    } 

    // 2D to 1D mapping accessor for constant Matrix 
    int operator()(size_t row, size_t column) const 
    { 
     // check bounds here if you want to 
     return mMat(row+mStartRow, column+mStartColumn); 
    } 

    // dimension accessors 
    size_t getRows() const 
    { 
     return mRows; 
    } 
    size_t getColumns() const 
    { 
     return mColumns; 
    } 

    // build a new Matrix based on this view 
    Matrix clone() 
    { 
     Matrix result(mRows, mColumns); 
     for (size_t row = 0; row < mRows; ++row) 
     { 
      for (size_t col = 0; col < mColumns; ++col) 
      { 
       result(row, col) = mMat(row+mStartRow, col+mStartColumn); 
      } 
     } 
     return result; 
    } 
}; 

以及使用该吸盘的一个示例:

// stream formatters 
std::ostream & operator<<(std::ostream & out, const Matrix & mat) 
{ 
    for (size_t row = 0; row < mat.getRows(); ++row) 
    { 
     for (size_t col = 0; col < mat.getColumns(); ++col) 
     { 
      std::cout << std::setw(5) << mat(row, col); 
     } 
     std::cout << '\n'; 
    } 
    return out; 
} 
std::ostream & operator<<(std::ostream & out, const MatrixView & mat) 
{ 
    for (size_t row = 0; row < mat.getRows(); ++row) 
    { 
     for (size_t col = 0; col < mat.getColumns(); ++col) 
     { 
      std::cout << std::setw(5) << mat(row, col); 
     } 
     std::cout << '\n'; 
    } 
    return out; 
} 


int main() 
{ 
    Matrix one(6, 6); // make 6x6 matrix 
    int count = 0; 

    // set inputs to make errors really stand out 
    for (size_t row = 0; row < one.getRows(); ++row) 
    { 
     for (size_t col = 0; col < one.getColumns(); ++col) 
     { 
      one(row, col) = count++; 
     } 
    } 

    // print initial matrix 
    std::cout << one << '\n'; 

    // make a view of matrix that leaves off the outside. 
    MatrixView view(1,1,5,5, one); 

    // print the view 
    std::cout << view << '\n'; 

    // get a clone of the view we can pass into a function 
    Matrix clone = view.clone(); 

    // and print the clone 
    std::cout << clone << '\n'; 
} 
+0

在我的创作中,更好的矩阵视图有一个指针,宽度,高度和步幅。不要将它绑定到仅包装矩阵。 – Yakk