質問

C ++では、次のようなことをしたいです。

int n = get_int_from_user();

char* matrix = new char[n][n];

matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';

delete [][] matrix;

もちろん、これは機能しません。同様のことをする最良の方法は何ですか?これに対するいくつかの解決策を見てきましたが、それらはかなり厄介に見えます。

役に立ちましたか?

解決

手動の動的な方法:

width * heightの配列が必要だとしましょう。最も効率的な方法は、1次元配列を使用することです:

char *matrix = new char[width*height];

削除するには:

delete[] matrix;

アクセスするには:

char getArrayValue(char *matrix, int row, int col)
{
  return matrix[row + col*width];
}

変更するには:

void setArrayValue(char *matrix, int row, int col, char val)
{
  matrix[row + col*width] = val;
}

ブーストマトリックス:

boost :: matrixの使用を検討依存関係を持つことができる場合。

その後、 boost linearに結び付けることができます。代数ライブラリ。

いくつかのブーストのサンプルコード: :matrix

#include <boost/numeric/ublas/matrix.hpp>
using namespace boost::numeric::ublas;
matrix<char> m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
    for (unsigned j = 0; j < m.size2 (); ++ j)
        m (i, j) = 3 * i + j;

一部のコンパイラのスタック:

一部のコンパイラでは、実行時に決定されたサイズでスタック上に配列を作成できます。 g ++はそのようなコンパイラの例です。ただし、デフォルトでVC ++でこれを行うことはできません。

したがって、g ++ではこれは有効なコードです:

int width = 10;
int height = 10; 
int matrix[width][height];

ドリューホールは、このC99機能は可変長配列(VLA)と呼ばれ、現代のコンパイラーでおそらくオンにできると述べました。

他のヒント

私は通常、次のようなことをしています:

char *matrix = new char [width * height];

matrix[i + j * width] = 'c'; // same as matrix[i][j] = 'c';

delete [] matrix;

std::vector< std::vector<int> > array2d;はどうですか?

C ++(C with classes)の要点が欠けているようです:-)。これは、クラスがそれを実装することを求めている一種の使用です。

あなたはあなたが探しているデータ構造を持っていると確信しているSTLまたは他のサードパーティのクラスライブラリを使用するだけでできますが、もしあなたが自分でロールする必要があるなら、クラスを作成するだけです次のプロパティを使用します。

  • nを指定すると、char(charcharなど)の新しいn * n配列を作成するだけのコンストラクタ。
  • 単にcharray [x * n + y]を参照するx.yに基づいて値を取得および設定するメンバー関数
  • 配列を削除するデストラクタ[]。

真の2次元配列の場合:

int n = get_int_from_user();

char** matrix = new char*[n];
for (int i = 0; i < n; i++) {
    matrix[i] = new char[n];
}

// Operations on matrix.

for (int i = 0; i < n; i++) {
    delete [] matrix[i];
}
delete matrix;

頭のてっぺんから。間違い、間違いありません。しかし、他の人がよりエレガントなアプローチを投稿していると思います。

boost :: multi_array

手作業で行うのは面倒です。

幅を個別に追跡する必要がないように、データメンバーをクラスにラップする拡張機能を備えた1次元配列アプローチ(Brian R. Bondyによる選択された回答)が好きです:

class Matrix
{
    int width;
    int height;
    char* data;
public:
    Matrix();
    Matrix(int width, int height);
    ~Matrix();

    char getArrayValue(int row, int col);
    void setArrayValue(int row, int col, char val);
}

実装は読者向けの演習です。 ;)

これは良いものになると思います。

int n = get_int_from_user();

char **matrix=new (char*)[n];

for(int i=0;i<n;i++)
    matrix[i]=new char[n];

matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';

for(int i=0;i<n;i++)
    delete []matrix;
delete []matrix;
std::vector<int> m;

次に、実行時にm.resize()を呼び出します。

int* matrix = new int[w*h];

ガウス消去法のような何かをしたい場合は、行列をすべきです

int** matrix = new int*[h];
for(size_t i(0); i < h; ++i)
    matrix[i] = new int[w];

(ガウス消去法では通常、行を別の行と交換する必要があるため、線形時間でコピーしてスワップするのではなく、一定の時間で行へのポインターをスワップする方が良いです。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top