4

の形式で読み取り/書き込みを行う必要がある単純なMatrixクラスがありますa[index1][index2]

例えば:

Matrix a;

a[1][2] = 5;

それをC++でどのように実装しますか?ありがとう。

4

4 に答える 4

6

これは、まさにあなたが望むことを実行する素晴らしい基本実装です。

更新(2013年9月26日):コードを大幅に改善しました。

テンプレートのタイプTは、の要件を満たす必要があるだけstd::vectorです。

#include <vector>
#include <stdexcept>

template<typename T>
class matrix {
    class row {
        std::vector<T> values;
    public:
        row(std::size_t n)
            : values(n, T()) {}

        T& operator[] (std::size_t index) {
            if (index < values.size())
                return values[index];
            else
                throw std::domain_error("Matrix column index out of bounds.");
        }
        const T& operator[] (std::size_t index) const {
            if (index < values.size())
                return values[index];
            else
                throw std::domain_error("Matrix column index out of bounds.");
        }

        std::size_t size() const { return values.size(); }
    };

    std::vector<row> rows;

public:
    matrix(std::size_t m, std::size_t n)
        : rows(m, row(n)) {}

    row& operator[](std::size_t index) {
        if (index < rows.size())
            return rows[index];
        else
            throw std::domain_error("Matrix row index out of bounds.");
    }
    const row& operator[](std::size_t index) const {
        if (index < rows.size())
            return rows[index];
        else
            throw std::domain_error("Matrix row index out of bounds.");
    }

    std::size_t row_count() const { return rows.size(); }
    std::size_t col_count() const {
        if (rows.size()) return rows[0].size();
        return 0;
    }

    std::size_t size() const { return row_count() * col_count(); }
};

便宜上、このヘルパーを使用してマトリックスを印刷できます。

#include <ostream>

template<typename T>
std::ostream& operator <<(std::ostream& o, const matrix<T>& mat) {
    for (std::size_t i = 0u; i < mat.row_count(); ++i) {
        for (std::size_t j = 0u; j < mat.col_count(); ++j) {
            o << mat[i][j] << ' ';
        }
        o << '\n';
    }
    return o;
}

そしてあなたのためだけに、これをテストするための使用例:

int main() {
    matrix<int> mat_0(2, 3);
    matrix<double> mat_1(1, 2);

    mat_0[0][0] = 2;
    mat_0[0][1] = 3;
    mat_0[0][2] = 4;
    mat_0[1][0] = 3;
    mat_0[1][1] = 7;
    mat_0[1][2] = 9;

    mat_1[0][0] = 0.43;
    mat_1[0][1] = 213.01;

    std::cout << mat_0;
    std::cout << '\n';
    std::cout << mat_1;

    return 0;
}
于 2013-03-24T12:47:26.140 に答える
6

Matrix::operator[]マトリックス内の列を表すヘルパークラスを返すように、オーバーロードする必要があります。そのヘルパークラスはoperator[]、その列内の要素にアクセスするためにオーバーロードする必要もあります。

ただし、この方法で実装すると、複雑になりすぎる可能性があります。代わりに、実装operator()して2つのインデックスを引数として使用する方が簡単な場合があります。

int& Matrix::operator()(int i, int j)
{
  return internal_array[i][j];
}
于 2013-03-24T12:47:58.120 に答える
2

要素にrefを返すネストclass RowTypeを定義し、の要素にrefを返すようにを定義します。operator[]MatrixMatrix operator []RowType

これがテーマのバリエーションです(最初の答えの周り)。int、double、complex、(string !?)などを使用するためにnew-delete .. ahとtemplateを使用しないでください。これは完全な実装ではなく、デバッグもしていません。それは単なるアイデアです。

#include <vector>

template <typename Num>
class Matrix {
   public:
    class RowType 
    { public:
       RowType () { }
       RowType (unsigned int columnCount):values(columnCount,Num()) {}
             int& operator[](unsigned int index)     {return values[index];}
       const int& operator[](unsigned int index)const{return values[index];}

       std::vector<Num> values;
    };

    Matrix() {  }
    Matrix(unsigned int rowCount, unsigned int columnCount)
              :rows(rowCount, MatrixRow<Num>(columnCount) )  {}
          RowType& operator[](unsigned int index)     {return rows[index]);}
    const RowType& operator[](unsigned int index)const{return rows[index]);}

  private:  std::vector<RowType<Num>> rows;
};

....
Matrix<int> a(10,10);
a[9][9]=1;
于 2013-03-24T12:50:32.003 に答える
1

たとえば、1d Matrixクラスを作成し、Matrix1Dその[]演算子をオーバーロードして、特定のインデックスの値にアクセスできるようにすることができます。

次に、2d Matrixクラスを作成し、Matrix2Dその演算子をオーバーロードして、それに含まれるクラス[]の1つにアクセスできるようにします。Matrix1D

そうすれば、aMatrix2D)からMatrix1Dwithに遷移し[]、次に2番目の値に遷移します[]

于 2013-03-24T12:48:39.397 に答える