динамический двумерный массив в соответствии с входом - PullRequest
4 голосов
/ 07 февраля 2010

Мне нужно получить вход N от пользователя и сгенерировать матрицу N * N. Как я могу объявить матрицу? Как правило, размер массива и матрицы должны быть зафиксированы в объявлении, верно? А как насчет vector<vector<int>>? Я никогда не использовал это раньше, поэтому мне нужно предложение от ветерана.

Ответы [ 3 ]

17 голосов
/ 07 февраля 2010

A vector<vector<int> > (обратите внимание на пробел в > >) может работать хорошо, но это не обязательно самый эффективный способ сделать что-то. Другой способ, который может работать довольно хорошо, - это обертка вокруг одного вектора, которая отслеживает «форму» представляемой матрицы и предоставляет функцию или перегруженный оператор для доступа к данным:

template <class T>
class matrix { 
    int columns_;
    std::vector<T> data;
public:
    matrix(int columns, int rows) : columns_(columns), data(columns*rows) {}

    T &operator()(int column, int row) { return data[row*columns_+column]; }
};

Обратите внимание, что стандарт C ++ позволяет operator[] принимать только один операнд, поэтому вы не можете использовать его для этой работы, по крайней мере, напрямую. В приведенном выше примере я (очевидно, достаточно) вместо этого использовал operator(), поэтому подписки выглядят больше как Fortran или BASIC, чем вы привыкли в C ++. Если вы действительно используете нотацию [], вы можете сделать это в любом случае, хотя это немного сложнее (вы перегружаете его в классе матрицы для возврата прокси, а затем прокси-класс также перегружает operator[] для возврата (a ссылка на) правильный элемент - он внутренне слегка уродлив, но в любом случае работает отлично).

Редактировать: Так как я лежу без дела, вот пример того, как реализовать последнее. Я написал это (довольно давно), прежде чем большинство компиляторов включили std::vector, поэтому он статически выделяет массив вместо использования вектора. Это также для случая с 3D (так что задействованы два уровня прокси), но, если повезет, основная идея все равно дойдет до конца:

template<class T, int size>
class matrix3 {

    T data[size][size][size];

    friend class proxy;
    friend class proxy2;

    class proxy { 
        matrix3 &m_;
        int index1_, index2_;
    public:
        proxy(matrix3 &m, int i1, int i2) 
            : m_(m), index1_(i1), index2_(i2) 
        {}

        T &operator[](int index3) { 
            return m_.data[index1_][index2_][index3];
        }
    };

    class proxy2 { 
        matrix3 &m_;
        int index_;
    public:
        proxy2(matrix3 &m, int d) : m_(m), index_(d) { }

        proxy operator[](int index2) { 
            return proxy(m_, index_, index2);
        }
    };
public:
    proxy2 operator[](int index) {
        return proxy2(*this, index);
    }
};

Используя это, вы можете обращаться к массиву с обычным синтаксисом C ++, например:

matrix3<double, size> m;

for (int x=0; x<size; x++)
    for (int y = 0; y<size; y++)
        for (int z = 0; z<size; z++)
            m[x][y][z] = x*100 + y * 10 + z;
3 голосов
/ 07 февраля 2010

Boost реализует матрицы (поддерживающие математические операции) в своей библиотеке uBLAS и предоставляет синтаксис использования, подобный следующему.

#include <boost/numeric/ublas/matrix.hpp>

int main(int argc, char* argv[])
{
    unsigned int N = atoi(argv[1]);
    boost::matrix<int> myMatrix(N, N);

    for (unsigned i = 0; i < myMatrix.size1 (); ++i)
        for (unsigned j = 0; j < myMatrix.size2 (); ++j)
            myMatrix(i, j) = 3 * i + j;

    return 0;
}
0 голосов
/ 09 октября 2015

Пример кода:

template<class T>
class Array2D
{
public:
    Array2D(int a, int b)  
    {
        num1 = (T**)new int [a*sizeof(int*)];
        for(int i = 0; i < a; i++)
            num1[i] = new int [b*sizeof(int)];

        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++) {
                num1[i][j] = i*j;
            }
        }
    }
    class Array1D
    {
    public:
        Array1D(int* a):temp(a) {}
        T& operator[](int a)
        {
            return temp[a];
        }
        T* temp;
    };

    T** num1;
    Array1D operator[] (int a)
    {
        return Array1D(num1[a]);
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    Array2D<int> arr(20, 30);

    std::cout << arr[2][3];
    getchar();
    return 0;
}

    enter code here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...