2017-07-26 10 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)と同じである。 新しいベクトルを作成せずにそれを行うことは可能ですか?関数へのポインタを渡すだけですか?2次元ベクトルのサブベクトルをC++の関数で渡す方法

+2

簡単な(そして最も速い、すなわち、最適化)を行うための方法2Dから1Dに平坦 'ベクトル'及びマップを使用することで、副-versa。 – vsoftco

+1

両方のディメンションをスライスしたい場合は、各ディメンションの最初と最後のインデックスを渡して、参照*で渡すベクタを編集することができます。 –

+0

ベクトルを使用してパラメータとしてパラメータを渡すと、ジョブが完了します。 – MASh

答えて

0

部分行列を参照するか、または境界領域を編集したい場合は、ビューアを作成します。ビューアは何もしませんが、見ることが許されているマトリックスの領域を制限します。コピーも余分なメモリもほとんどありません。たとえば、巨大な画像があり、8x8の要素領域を表示して操作したい場合は、これは素晴らしいことです。

特定のビューの新しいマトリックスが必要な場合は、ビューに基づいて、そのビューに基づいて新しいマトリックスを作成するよう教えてください。この場合にはコピーがありますが、コピーが必要な場合はコピーを避けるのが難しいです。

まず、私は殴られた道をちょっとさまようつもりです。これを速くしたい場合(そして速くしたくない人は)vector<vector>を使用しないでください。 A vectorはメモリ内で連続していることが保証されていますが、ウィンドウ外に出ることを保証するベクタのベクタを持つと、空間的なローカリティが悪くなり、通常はキャッシュの使用状況が悪くなります。

Matrixクラスの単純な例を示します。Matrixクラスは、扱いが簡単でメモリチャンクがすべて1つで、よりキャッシュフレンドリな傾向があります。

// 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

関連する問題