Как Вы динамично выделяете матрицу?

Как Вы динамично выделяете 2D матрицу в C++? Я попробовал на основе того, что я уже знаю:

#include <iostream>

int main(){
    int rows;
    int cols;
    int * arr;
    arr = new int[rows][cols];
 }

Это работает на один параметр, но теперь на два. Что я должен сделать?

20
задан chustar 10 September 2009 в 02:53
поделиться

8 ответов

Матрица на самом деле представляет собой массив массивов.

int rows = ..., cols = ...;
int** matrix = new int*[rows];
for (int i = 0; i < rows; ++i)
    matrix[i] = new int[cols];

Конечно, чтобы удалить матрицу, вы должны сделать следующее:

for (int i = 0; i < rows; ++i)
    delete [] matrix[i];
delete [] matrix;

Я только что выяснил другую возможность:

int rows = ..., cols = ...;
int** matrix = new int*[rows];
if (rows)
{
    matrix[0] = new int[rows * cols];
    for (int i = 1; i < rows; ++i)
        matrix[i] = matrix[0] + i * cols;
}

Освободить этот массив проще:

if (rows) delete [] matrix[0];
delete [] matrix;

Это решение имеет то преимущество, что для всех элементов выделяется один большой блок памяти вместо нескольких маленьких фрагментов. Первое решение, которое я опубликовал, является лучшим примером концепции массивов .

52
ответ дан 29 November 2019 в 22:26
поделиться

Вы также можете использовать std :: vectors для достижения этой цели:

используя std :: vector >

Пример:

std::vector< std::vector<int> > a;

  //m * n is the size of the matrix

    int m = 2, n = 4;
    //Grow rows by m
    a.resize(m);
    for(int i = 0 ; i < m ; ++i)
    {
        //Grow Columns by n
        a[i].resize(n);
    }
    //Now you have matrix m*n with default values

    //you can use the Matrix, now
    a[1][0]=1;
    a[1][1]=2;
    a[1][2]=3;
    a[1][3]=4;

//OR
for(i = 0 ; i < m ; ++i)
{
    for(int j = 0 ; j < n ; ++j)
    {      //modify matrix
        int x = a[i][j];
    }

}
24
ответ дан 29 November 2019 в 22:26
поделиться

Попробуйте boost :: multi_array

#include <boost/multi_array.hpp>

int main(){
    int rows;
    int cols;
    boost::multi_array<int, 2> arr(boost::extents[rows][cols] ;
}
16
ответ дан 29 November 2019 в 22:26
поделиться
 #include <iostream>

    int main(){
        int rows=4;
        int cols=4;
        int **arr;

        arr = new int*[rows];
        for(int i=0;i<rows;i++){
           arr[i]=new int[cols];
        }
        // statements

        for(int i=0;i<rows;i++){
           delete []arr[i];
        }
        delete []arr;
        return 0;
     }
3
ответ дан 29 November 2019 в 22:26
поделиться
arr = new int[cols*rows];

Если вы не возражаете против синтаксиса

arr[row * cols + col] = Aij;

, либо где-нибудь примените перегрузку оператора []. Это может быть более удобным для кеширования, чем массив массивов, а может и нет, более вероятно, вам не стоит об этом заботиться. Я просто хочу отметить, что а) массив массивов - это не только решение, б) некоторые операции легче реализовать, если матрица находится в одном блоке памяти. Например,

for(int i=0;i < rows*cols;++i)
   matrix[i]=someOtherMatrix[i];

на одну строку короче, чем

for(int r=0;i < rows;++r)
  for(int c=0;i < cols;++s)
     matrix[r][c]=someOtherMatrix[r][c];

, хотя добавление строк в такую ​​матрицу более болезненно

4
ответ дан 29 November 2019 в 22:26
поделиться

У меня есть класс сетки, который можно использовать как простую матрицу, если вам не нужны математические операторы.

/**
 * Represents a grid of values.
 * Indices are zero-based.
 */
template<class T>
class GenericGrid
{
    public:
        GenericGrid(size_t numRows, size_t numColumns);

        GenericGrid(size_t numRows, size_t numColumns, const T & inInitialValue);

        const T & get(size_t row, size_t col) const;

        T & get(size_t row, size_t col);

        void set(size_t row, size_t col, const T & inT);

        size_t numRows() const;

        size_t numColumns() const;

    private:
        size_t mNumRows;
        size_t mNumColumns;
        std::vector<T> mData;
};


template<class T>
GenericGrid<T>::GenericGrid(size_t numRows, size_t numColumns):
    mNumRows(numRows),
    mNumColumns(numColumns)
{
    mData.resize(numRows*numColumns);
}


template<class T>
GenericGrid<T>::GenericGrid(size_t numRows, size_t numColumns, const T & inInitialValue):
    mNumRows(numRows),
    mNumColumns(numColumns)
{
    mData.resize(numRows*numColumns, inInitialValue);
}


template<class T>
const T & GenericGrid<T>::get(size_t rowIdx, size_t colIdx) const
{
    return mData[rowIdx*mNumColumns + colIdx];
}


template<class T>
T & GenericGrid<T>::get(size_t rowIdx, size_t colIdx)
{
    return mData[rowIdx*mNumColumns + colIdx];
}


template<class T>
void GenericGrid<T>::set(size_t rowIdx, size_t colIdx, const T & inT)
{
    mData[rowIdx*mNumColumns + colIdx] = inT;
}


template<class T>
size_t GenericGrid<T>::numRows() const
{
    return mNumRows;
}


template<class T>
size_t GenericGrid<T>::numColumns() const
{
    return mNumColumns;
}
0
ответ дан 29 November 2019 в 22:26
поделиться

или вы можете просто выделить 1D-массив, но ссылаться на элементы в 2D-режиме:

для адресации строки 2, столбца 3 (верхний левый угол - строка 0, столбец 0):

arr [2 * MATRIX_WIDTH + 3]

, где MATRIX_WIDTH - количество элементов в строке.

1
ответ дан 29 November 2019 в 22:26
поделиться

Другой ответ, описывающий массивы массивов, правильный.
НО, если вы планируете что-то математическое с массивами - или вам нужно что-то особенное, например, разреженные матрицы, вам следует взглянуть на одну из множества математических библиотек, таких как TNT , прежде чем изобретать слишком много колес

0
ответ дан 29 November 2019 в 22:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: