1

n × n でない行列の転置を計算しようとしています。問題は、追加される各要素に新しいメモリを割り当てる必要があることです。**配列を削除する必要はありません。コードはそのようなものです。// 2 次元配列を初期化します。

array  = new int*[row];
    for (int i=0; i<row; i++){
        arr[i] = new int[col]();
    }

今、私の行列が 3*4 であると仮定する 1 つのケースだけを考えています。マトリックスの転置は薄暗い 4*3 です。私は次のコードを実行しますが、「SEGMENTATION FAULT」を与えています。アイデアは、転置の結果として追加される要素に新しいメモリを割り当てることです。コードは次のとおりです。

int r=col;
int c=row;
 if (col<c){
  arr  = new int*[row];
  for (int i=col; i<=c; i++){
  arr[i] = new int[col](); // trying to allocate New Memory to elem.
  }

ここでエラーが発生しています。任意のヘルプ。また、この問題を解決する他の方法がある場合は、提案してください。

4

2 に答える 2

3

アクセサー関数 (行列の operator(row,col) など) を含むラッパーを作成し、rows*cols サイズの 1 次元配列を内部的に使用します。

これにより、作業がはるかに簡単になり、このマトリックスのデータがまとめられます。これにより、小さなマトリックスのキャッシュが有利になる場合があります。

コメントでリクエストされた例を次に示します。目的によって非常に単純に保持され、テンプレートを使用しません。内部ストレージとしてベクトルを使用します。operator(..) を使用して行列要素にアクセスできます。

Matrix A(3,4);
// fill matrix
// you can access each element in a natural syntax as expected from math
int x = A(2,2);
A(2,2) = 3;

さらに、アサートの代わりに例外を使用して、インデックスのオーバーフローをチェックする必要があります。

// matrix.h
#include <vector>

class Matrix
{
public:
  Matrix(size_t rows, size_t cols);

  int& operator()(size_t row, size_t col);
  const int& operator()(size_t row, size_t col) const;

  int& operator[](size_t index);
  const int& operator[](size_t index) const;

  Matrix get_transposed() const;

  size_t compute_index(size_t row, size_t col) const;

  void print();

private:
  size_t  _rows;
  size_t  _cols;

  std::vector<int>  _data;

}; // class Matrix



// matrix.cpp 
#include "matrix.h"
#include <iostream>
#include <cassert>

Matrix::Matrix(size_t rows, size_t cols)
  : _rows(rows)
  , _cols(cols)
  , _data(rows*cols, 0)
{
}


int& Matrix::operator()(size_t row, size_t col)
{
  const size_t index = compute_index(row, col);
  assert(index < _data.size());
  return _data[index];
}

const int& Matrix::operator()(size_t row, size_t col) const
{
  const size_t index = compute_index(row, col);
  assert(index < _data.size());
  return _data[index];
}


int& Matrix::operator[](size_t index)
{
  return _data[index];
}

const int& Matrix::operator[](size_t index) const
{
  return _data[index];
}

size_t
Matrix::compute_index(size_t row, size_t col) const
{
  // here you should check that: 
  // row < rows
  // col < cols
  // and throw an exception if it's not
  assert(row<_rows);
  assert(col<_cols);

  return row * _cols + col;
}

Matrix
Matrix::get_transposed() const
{
  Matrix t(_cols,_rows); 

  for(size_t row = 0; row < _rows; ++row)
    for(size_t col = 0; col < _cols; ++col)
    {
      t(col,row) = (*this)(row,col);
    }
  return t;
}
于 2012-11-30T15:10:30.480 に答える
3

2 番目のコード サンプルでは、​​配列の制限を超えて記述します。からまで数えた長さarrrow要素です。forループでは、インデックスは、配列と同等で、配列を1つ超えた要素から始まります。正しいコードは代わりになります0row - 1icolcrow<<=

for (int i=col; i < c; i++){
    arr[i] = new int[col](); // trying to allocate New Memory to elem.
}

それとは別に、Wikipedia: Transposeをご覧になることをお勧めします。これは、2 番目のケースでは、行と列を切り替えただけで最初のコード サンプルを使用できるためです。

于 2012-11-30T15:12:53.903 に答える