2015-04-26 3 views
0

Для C++, я видел несколько рекомендаций использовать 2D массивов следующим образом:Как обобщить простые 2D-массивы?

int* theArray = new int[d1 * d2]; 

Элемент (I, J), то можно получить следующим образом:

int myInt = theArray[i + d2 * j]; 

У меня два вопроса : Во-первых, как получить доступ к 3D-массиву? Существует ли общая формула? Второе и более важное, будет ли штраф за исполнение, если я буду использовать функции

int getNumber(int i, int j, int k) 
void setNumber(int i, int j, int k, int theValue) 

для извлечения и установки номера? Я не хочу вкручивать его где-то в коде, а затем трать навсегда найти, где этот винт.

+0

Индексирование - это 'i + d2 * j + d2 * d3 * k', но это основной математический вопрос, а не программирование. –

+0

btw, это зависит от порядка размеров. –

+0

Поскольку это помечено 'array', я просто должен был ответить: используйте' std :: array', если требуется установить размер времени выполнения, std :: vector. Оптимизируйте далее только после профилирования. –

ответ

1

Обобщение на три измерения не сложно:

int* theArray = new int[d1*d2*d3]; 

и доступ к нему с помощью

int myInt = theArray[i+d1*(j+d2*k)]; 

Так же, как десятичной системе, например. Когда вы пишете 123 как 3 + 10 * 2 + 100 * 3 = 3 + 10 * (2 + 10 * 3). Где 10 - размер каждого измерения. Обратите внимание, что я изменил ваш d2 на d1, так как отступом является размер измерения, связанный с индексом i.

Что касается вашего второго вопроса, функция, называемая функцией, может уменьшить производительность. Но вы можете избежать этой проблемы с помощью функции или определить macro, которая тогда эквивалентна вообще не вызову функции, касающейся производительности.

1

Я бы сказал, что для 2D массива, предполагая, что i является первым индексом и j является вторым, это лучше делать индексацию как

int myInt = theArray[i*d2 + j]; 

поэтому изменение последнего индекса дает непрерывный диапазон. Так реализуются многомерные массивы C и C++.

Так что, если ваш 3D массив

int* theArray = new int[d1*d2*d3]; 

Затем к нему доступ таким образом:

int myInt = theArray[(i*d2 + j)*d3 + k]; 

о функциях аксессоры - если они рядный, накладные расходы будут равны нулю. Вы можете также обернуть это все в свой собственный класс массивов (но это, вероятно, то, что вы уже намереваетесь сделать)

0

Вместо этого я бы пошел с std::array и не делал никаких ручных индексов. Просто убедитесь, что последний индекс - тот, который вы, скорее всего, перевернете. std :: array работает как [].

#include <iostream> 
#include <array> 

int main() { 

    constexpr size_t a=5; 
    constexpr size_t b=4; 
    constexpr size_t c=3; 

    std::array<std::array<std::array<float,a>, b>, c> arr3d; 

    for(auto& outer : arr3d){ 
     for(auto& row : outer){ 
     for(auto& place : row){ 
      place=3.5; 
     } 
     } 
    } 

    for(size_t i=0;i<a; ++i){ 
     for(size_t j=0;j<b; ++j){ 
     for(size_t k=0;k<c; ++k){ 
      arr3d[i][j][k]=k; // or whatever 
     } 
     } 
    } 

    std::cout << arr3d[0][1][2] << std::endl; 
} 

Если вам нужно времени выполнения гибкость размеров, используйте std::vector.

template<typename T> using Vec = std::vector<T>;  
Vec<Vec<Vec<float>>> arr3d(a,Vec<Vec<float>>(b,Vec<float>(c,0))); 

но это будет значительно медленнее для инициализации и в зависимости от того, как вы используете его (и значения а, б, в) доступ будет медленнее также. (примечание комментарии).

Для других способов инициализировать массив: Other ways to initialize the array

+0

вы предполагаете, что размер известен во время компиляции. –

+0

Да. Я обновил, как вместо этого использовать std :: vector. –

+0

Если вы хотите убить производительность, непременно ... –

Смежные вопросы