Трехмерные массивы целых чисел в C++

Чтобы увеличить размер кучи в IntelliJ IDEA, следуйте приведенным ниже инструкциям. Это работало для меня.

Для пользователей Windows

Перейдите в место, где установлена ​​среда IDE, и выполните поиск следующего.

idea64.exe.vmoptions

Отредактируйте файл и добавьте следующее.

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m

Вот и все!

7
задан Matt 27 January 2015 в 09:56
поделиться

6 ответов

Взгляните на библиотеку многомерного массива Повышения. Вот пример (адаптирован из документации Повышения):

#include "boost/multi_array.hpp"

int main() {
  // Create a 3D array that is 20 x 30 x 4
  int x = 20;
  int y = 30;
  int z = 4;

  typedef boost::multi_array<int, 3> array_type;
  typedef array_type::index index;
  array_type my_array(boost::extents[x][y][z]);

  // Assign values to the elements
  int values = 0;
  for (index i = 0; i != x; ++i) {
    for (index j = 0; j != y; ++j) {
      for (index k = 0; k != z; ++k) {
        my_array[i][j][k] = values++;
      }
    }
  }
}
11
ответ дан 6 December 2019 в 07:53
поделиться

Каждая пара квадратных скобок является операцией разыменования (при применении к указателю). Как пример, следующие пары строк кода эквивалентны:

x = myArray[4];
x = *(myArray+4);

 

x = myArray[2][7];
x = *((*(myArray+2))+7);

Для использования предложенного синтаксиса, Вы просто разыменовываете значение, возвращенное, сначала разыменовывают.

int*** myArray = (some allocation method, keep reading);
//
// All in one line:
int   value = myArray[x][y][z];
//
// Separated to multiple steps:
int** deref1 = myArray[x];
int*  deref2 = deref1[y];
int   value = deref2[z];

Для движения о выделении этого массива просто необходимо распознать, что у Вас на самом деле нет трехмерной антенной решетки целых чисел. У Вас есть массив массивов массивов целых чисел.

// Start by allocating an array for array of arrays
int*** myArray = new int**[X_MAXIMUM];

// Allocate an array for each element of the first array
for(int x = 0; x < X_MAXIMUM; ++x)
{
    myArray[x] = new int*[Y_MAXIMUM];

    // Allocate an array of integers for each element of this array
    for(int y = 0; y < Y_MAXIMUM; ++y)
    {
        myArray[x][y] = new int[Z_MAXIMUM];

        // Specify an initial value (if desired)
        for(int z = 0; z < Z_MAXIMUM; ++z)
        {
            myArray[x][y][z] = -1;
        }
    }
}

Освобождение этого массива следует за подобным процессом к выделению его:

for(int x = 0; x < X_MAXIMUM; ++x)
{
    for(int y = 0; y < Y_MAXIMUM; ++y)
    {
        delete[] myArray[x][y];
    }

    delete[] myArray[x];
}

delete[] myArray;
5
ответ дан 6 December 2019 в 07:53
поделиться

Нужно отметить, что во всех отношениях, Вы имеете дело только с 2D массивом, потому что третье (и младший значащий) размер известно.

Используя STL или Повышение довольно хорошие подходы, если Вы не знаете заранее, сколько записей Вы будете иметь в каждом размере массива, потому что они дадут Вам динамическое выделение памяти, и я рекомендую или этих подходов, если Ваш набор данных должен остаться в основном статичным, или если это, чтобы главным образом только получить новые записи и не много удалений.

Однако, если Вы знаете что-то о своем наборе данных заранее, такой как примерно, сколько объектов всего будет сохранено, или если массивы должны быть малонаселенными, Вы могли бы быть более обеспеченным использованием некоторой функции хеша/блока и использовать индексы XYZ в качестве Вашего ключа. В этом случае, принимая не больше, чем 8 192 записи (на 13 битов) на размер, Вы могли обойтись 40-разрядным (5-байтовым) ключом. Или, принятие там всегда является записями 4 x Z, Вы просто использовали бы 26-разрядный ключ XY. Это - один из более эффективных компромиссов между скоростью, использованием памяти и динамическим выделением.

1
ответ дан 6 December 2019 в 07:53
поделиться

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

Если Вы действительно полагаете, что необходимо создать пользовательский 3-й тип вектора, исследовать Повышение сначала.

// a class that does something in 3 dimensions

class MySimpleClass
{
public:

  MySimpleClass(const size_t inWidth, const size_t inHeight, const size_t inDepth) :
   mWidth(inWidth), mHeight(inHeight), mDepth(inDepth)
   {
       mArray.resize(mWidth * mHeight * mDepth);
   }


  // inline for speed
  int Get(const size_t inX, const size_t inY, const size_t inZ) {
     return mArray[(inZ * mWidth * mHeight) + (mY * mWidth) + mX];
  }

  void Set(const size_t inX, const size_t inY, const size_t inZ, const int inVal) {
     return mArray[(inZ * mWidth * mHeight) + (mY * mWidth) + mX];
  }

  // doing something uniform with the data is easier if it's not a vector of vectors
  void DoSomething()
  {
     std::transform(mArray.begin(), mArray.end(), mArray.begin(), MyUnaryFunc);
  }

private:

  // dimensions of data
  size_t mWidth;
  size_t mHeight;
  size_t mDepth;

  // data buffer
  std::vector< int > mArray;
};
1
ответ дан 6 December 2019 в 07:53
поделиться

Предложение Pieter хорошо, конечно, но одна вещь, которую необходимо принять во внимание, состоит в том, который в случае больших массивов, создающих его, может быть довольно медленным. Каждый раз полные изменения вектора, все данные должны быть скопированы вокруг ('n' векторы векторов).

-2
ответ дан 6 December 2019 в 07:53
поделиться

С векторами:

std::vector< std::vector< std::vector< int > > > array3d;

Каждый элемент является доступным остроумием array3d [x] [y] [z], если элемент был уже добавлен. (например, через push_back)

2
ответ дан 6 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

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