71

2D マトリックスの次元の入力を取り込もうとしています。次に、ユーザー入力を使用してこのマトリックスに入力します。私がこれをやろうとした方法は、ベクトル(ベクトルのベクトル)によるものです。しかし、データを読み込んで行列に追加しようとすると、エラーが発生しました。

//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
    for(int j = 0; j<CC; j++)
    {
    cout<<"Enter the number for Matrix 1";
         cin>>matrix[i][j];
    }
}

これを行おうとすると、添え字が範囲外のエラーになります。何かアドバイス?

4

8 に答える 8

197

要素にアクセスする前に、ベクトルのベクトルを適切なサイズに初期化する必要があります。次のように実行できます。

// assumes using std::vector for brevity
vector<vector<int>> matrix(RR, vector<int>(CC));

これにより、で満たされたRRサイズベクトルのベクトルが作成されます。CC0

于 2012-09-11T20:33:20.767 に答える
86

現状では、ベクトルの両方の次元は0です。

代わりに、次のようにベクトルを初期化します。

vector<vector<int> > matrix(RR);
for ( int i = 0 ; i < RR ; i++ )
   matrix[i].resize(CC);

RR * CCこれにより、すべての要素がに設定された次元のマトリックスが得られます0

于 2012-09-11T18:19:57.500 に答える
12

私はC++に精通していませんが、ドキュメントをざっと見てみると、これでうまくいくはずです。

//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
    vector<int> myvector;
    for(int j = 0; j<CC; j++)
    {
        int tempVal = 0;
        cout<<"Enter the number for Matrix 1";
        cin>>tempVal;
        myvector.push_back(tempVal);
    }
    matrix.push_back(myvector);
}
于 2012-09-11T18:25:18.513 に答える
4

次のクラスがあるとします。

#include <vector>

class Matrix {
 private:
  std::vector<std::vector<int>> data;
};

まず、デフォルトのコンストラクターを実装することをお勧めします。

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

 private:
  std::vector<std::vector<int>> data;
};

この時点で、次のように Matrix インスタンスを作成できます。

Matrix one;

Reset次の戦略的ステップは、行列の新しい行数と列数をそれぞれ指定する 2 つの整数パラメーターを取るメソッドを実装することです。

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    if (rows == 0 || cols == 0) {
      data.assign(0, std::vector<int>(0));
    } else {
      data.assign(rows, std::vector<int>(cols));
    }
  }

 private:
  std::vector<std::vector<int>> data;
};

この時点で、Resetメソッドは 2D マトリックスの次元を指定された次元に変更し、そのすべての要素をリセットします。なぜこれが必要なのか、少し後で説明しましょう。

さて、マトリックスを作成して初期化できます。

Matrix two(3, 5);

マトリックスに info メソッドを追加しましょう。

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    data.resize(rows);
    for (int i = 0; i < rows; ++i) {
      data.at(i).resize(cols);
    }
  }

  int GetNumRows() const {
    return data.size();
  }

  int GetNumColumns() const {
    if (GetNumRows() > 0) {
      return data[0].size();
    }

    return 0;
  }

 private:
  std::vector<std::vector<int>> data;
};

この時点で、いくつかの簡単なマトリックス デバッグ情報を取得できます。

#include <iostream>

void MatrixInfo(const Matrix& m) {
  std::cout << "{ \"rows\": " << m.GetNumRows()
            << ", \"cols\": " << m.GetNumColumns() << " }" << std::endl;
}

int main() {
  Matrix three(3, 4);
  MatrixInfo(three);
}

この時点で必要な 2 番目のクラス メソッドはAt. プライベート データの一種のゲッター:

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    data.resize(rows);
    for (int i = 0; i < rows; ++i) {
      data.at(i).resize(cols);
    }
  }

  int At(const int &row, const int &col) const {
    return data.at(row).at(col);
  }

  int& At(const int &row, const int &col) {
    return data.at(row).at(col);
  }

  int GetNumRows() const {
    return data.size();
  }

  int GetNumColumns() const {
    if (GetNumRows() > 0) {
      return data[0].size();
    }

    return 0;
  }

 private:
  std::vector<std::vector<int>> data;
};

定数Atメソッドは、行番号と列番号を受け取り、対応するマトリックス セルに値を返します。

#include <iostream>

int main() {
  Matrix three(3, 4);
  std::cout << three.At(1, 2); // 0 at this time
}

同じパラメーターを持つ2 番目の非定数Atメソッドは、対応するマトリックス セルの値への参照を返します。

#include <iostream>

int main() {
  Matrix three(3, 4);
  three.At(1, 2) = 8;
  std::cout << three.At(1, 2); // 8
}

>>最後に、演算子を実装しましょう:

#include <iostream>

std::istream& operator>>(std::istream& stream, Matrix &matrix) {
  int row = 0, col = 0;

  stream >> row >> col;
  matrix.Reset(row, col);

  for (int r = 0; r < row; ++r) {
    for (int c = 0; c < col; ++c) {
      stream >> matrix.At(r, c);
    }
  }

  return stream;
}

そしてそれをテストします:

#include <iostream>

int main() {
  Matrix four; // An empty matrix

  MatrixInfo(four);
  // Example output:
  //
  // { "rows": 0, "cols": 0 }

  std::cin >> four;
  // Example input
  //
  // 2 3
  // 4 -1 10
  // 8 7 13

  MatrixInfo(four);
  // Example output:
  //
  // { "rows": 2, "cols": 3 }
}

範囲外チェックを自由に追加してください。この例がお役に立てば幸いです:)

于 2019-11-26T21:26:50.177 に答える
0

初期化したのはベクトルのベクトルであるため、例でマトリックスと名付けた元のベクトルに、挿入するベクトル(ベクトルの用語では「プッシュ」)を含める必要があります。

もう1つ、演算子「cin」を使用してベクトルに値を直接挿入することはできません。入力を受け取り、同じものをベクトルに挿入する変数を使用します。

これを試してください:

int num;
for(int i=0; i<RR; i++){

      vector<int>inter_mat;       //Intermediate matrix to help insert(push) contents of whole row at a time

      for(int j=0; j<CC; j++){
           cin>>num;             //Extra variable in helping push our number to vector
           vin.push_back(num);   //Inserting numbers in a row, one by one 
          }

      v.push_back(vin);          //Inserting the whole row at once to original 2D matrix 
}
于 2018-06-29T20:16:57.897 に答える