Два (или более) размерных динамически создаваемых массива в C ++ - PullRequest
1 голос
/ 14 ноября 2011

Я реализую алгоритм динамического программирования, который должен создать некоторую двухмерную память перед ее запуском (размер памяти зависит от параметров, также нет четких верхних границ для них). Я пытался использовать обычный 2-мерный массив C ++, но, очевидно, я не знаю второго измерения заранее, поэтому оно не сработало. Какой самый разумный способ добиться этого? Существуют ли какие-либо классы из стандартной библиотеки или boost, которые бы делали это так просто, как следовало бы?

Необходимая мне функциональность довольно проста: создать MxN, получить или установить матрицу [i] [j]

Ответы [ 4 ]

3 голосов
/ 14 ноября 2011

Единственное, что поразит меня: «1001» - безобразный способ : реализовать его как одномерный массив и выполнить двойное индексирование вручную, например:

value = arr[i*num_i + j];

Вы всегда можете написать класс, чтобы скрыть уродство ...

1 голос
/ 14 ноября 2011

Очень простой 2d массив требует всего несколько строк кода

template<typename T>
struct Matrix2d
{
    int rows, cols;
    std::vector<T> data;
    Matrix2d(int rows, int cols) : rows(rows), cols(cols), data(rows*cols)
    { }

    T operator()(int i, int j) const { return data[i*cols+j]; }
    T& operator()(int i, int j) { return data[i*cols+j]; }
};

Доступ к элементам осуществляется с использованием mat(i, j) для чтения и mat(i, j) = v для записи.

Как Джеймс КанзеДля специального случая двухмерного массива также легко получить стандартный синтаксис массива C ++ mat[i][j] и mat[i][j] = v для доступа к элементу, используя operator[] вместо operator():

    T* operator[](int i) { return &data[i*cols]; }
    const T* operator[](int i) const { return &data[i*cols]; }

.Однако решение становится все труднее распространить на большее число измерений (тривиальная проблема с обозначением mat(i, j, k)).

1 голос
/ 14 ноября 2011

Самый простой способ - использовать массив std :: vectors. Затем вы можете изменить размеры векторов в любое время.

Кроме того, если вы можете просто отложить создание массива до тех пор, пока не узнаете оба измерения, вы можете использовать boost.MultiArray. Я думаю, что это может быть больше, что вы ищете.

0 голосов
/ 14 ноября 2011

Похоже, что использование вектора было бы хорошей идеей, если вы либо не планируете много копировать его, либо не обращаете внимания на издержки копирования.Этот код не проверен, может быть не прав на 100%)

typedef std::vector< std::vector< int > > 2dVector;

2dVector vec( 2 );
vec[ 0 ].resize( someSize );
vec[ 1 ].resize( someSize );

vec[ 0 ][ 0 ] = 100;
//Keep on doing stuff here.

В качестве альтернативы вы можете использовать что-то вроде boost :: shared_array (или tr1 / c ++ 11 эквивалентов)для динамического выделения вашего массива (этот код также не проверен, может быть не прав):

typedef boost::shared_array< boost::shared_array< int > > 2dArray;

2dArray arr( new boost::shared_array< int >( firstDimensionSize ) );
BOOST_FOREACH( boost::shared_array< int >& inner, arr )
{
   inner = new int[ secondDimensionSize ];
}

arr[ 0 ][ 1 ] = 100;

РЕДАКТИРОВАТЬ: быстрый Google также показывает Boost многомерный массив библиотека.Я не пользовался им или много читал описание, но, возможно, стоит посмотреть на

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