【问题标题】:How to allocate & access 3D, 4D, 5D arrays?如何分配和访问 3D、4D、5D 数组?
【发布时间】:2015-10-09 15:05:55
【问题描述】:

如何使用一个 malloc 以连续的方式分配 3D、4D、5D 数组并访问各个项目?

类似这样的:

int* array = malloc(sizeof(int) * width * height);
int item = array[x + y * width];

【问题讨论】:

  • 和你刚才展示的一样。继续添加乘数。
  • 乘数?这个有公式吗?

标签: c++ visual-c++


【解决方案1】:

3D 数组是 2D 数组的数组。 4D 数组是 3D 数组的数组。你只需乘以你的其他维度。例如,一个 3D 数组可以这样分配:

int *array = malloc(sizeof(int) * width * height * depth);

一个 4D 数组可以通过乘以你的其他维度:

int *array = malloc(sizeof(int) * width * height * depth * other_dimension);

对于 5D、6D 等数组以此类推。

假设您可以访问数组的宽度和高度,您可以使用类似这样的方式访问元素(对于 3D 数组,很容易扩展):

int get_element(int x, int y, int z)
{
    return array[(z * width * height) + (y * width) + x];
}

对于 4D 数组:

int get_element(int x, int y, int z, int dimension_4)
{
    return array[(dimension_4 * width * height * depth) + (z * width * height) + (y * width) + x];
}

【讨论】:

  • 是的,但是您如何访问每个项目?在 3D、4D、5D 等中。
  • 是否可以在没有那么多乘法的情况下进行访问? :)
  • 我不知道。 Jared42 的答案需要相同数量的乘法,只是在一个循环中。
【解决方案2】:

在这里回答 (Setting pointer to arbitrary dimension array? ):

特别看computeIndex/computeIndexes

#include <cstddef>
#include <vector>

template <typename T>
class MultiArray
{
public:
    explicit MultiArray(const std::vector<size_t>& dimensions) :
        dimensions(dimensions),
        values(computeTotalSize(dimensions))
    {
        assert(!dimensions.empty());
        assert(!values.empty());
    }

    const T& get(const std::vector<size_t>& indexes) const
    {
        return values[computeIndex(indexes)];
    }
    T& get(const std::vector<size_t>& indexes)
    {
        return values[computeIndex(indexes)];
    }

    size_t computeIndex(const std::vector<size_t>& indexes) const
    {
        assert(indexes.size() == dimensions.size());

        size_t index = 0;
        size_t mul = 1;

        for (size_t i = 0; i != dimensions.size(); ++i) {
            assert(indexes[i] < dimensions[i]);
            index += indexes[i] * mul;
            mul *= dimensions[i];
        }
        assert(index < values.size());
        return index;
    }

    std::vector<size_t> computeIndexes(size_t index) const
    {
        assert(index < values.size());

        std::vector<size_t> res(dimensions.size());

        size_t mul = values.size();
        for (size_t i = dimensions.size(); i != 0; --i) {
            mul /= dimensions[i - 1];
            res[i - 1] = index / mul;
            assert(res[i - 1] < dimensions[i - 1]);
            index -= res[i - 1] * mul;
        }
        return res;
    }

private:
    size_t computeTotalSize(const std::vector<size_t>& dimensions) const
    {
        size_t totalSize = 1;

        for (auto i : dimensions) {
            totalSize *= i;
        }
        return totalSize;
    }

private:
    std::vector<size_t> dimensions;
    std::vector<T> values;
};

int main()
{
    MultiArray<int> m({3, 2, 4});

    m.get({0, 0, 3}) = 42;
    m.get({2, 1, 3}) = 42;

    for (size_t i = 0; i != 24; ++i) {
        assert(m.computeIndex(m.computeIndexes(i)) == i);
    }
}

Demo

【讨论】:

    【解决方案3】:

    数组本质上是作为单一维度分配的。您通过计算索引的方式赋予它们维度。您需要分配的大小是标量元素的大小乘以您打算使用的每个维度中的元素数,例如,如果您想要一个 10 x 20 x 30 的 4 字节元素数组,则乘以 4 x 10 x 20 x 30 以获得您需要的 malloc 的大小。然后,我可能会编写一个函数,例如 my_index(int i, int j, int k),它可以计算任何有效 (i,j,k) 组合的一维索引。这个想法可以扩展到任意多的维度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-08
      • 2021-08-06
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      • 2021-09-27
      • 2021-10-14
      • 1970-01-01
      相关资源
      最近更新 更多