简体   繁体   English

任意维数组

[英]Arbitrary Dimensional Array

So I'm trying to create an n-dimensional array structure for use in a maze generating program. 所以我正在尝试创建一个用于迷宫生成程序的n维数组结构。

I've simplified my problem (for the purposes of trying to get the theory figured out before making it templatized and adding all the necessary helper functions) 我已经简化了我的问题(为了试图在使其理论化并添加所有必要的辅助函数之前弄清楚理论)

So my problem currently boils down to wanting to make an ArbitraryArray class that takes in an argument to its constructor specifying the number of dimensions. 所以我的问题目前归结为想要创建一个ArbitraryArray类,该类接受一个指定维数的构造函数的参数。 Each dimension will have length = 5. (for now) 每个维度的长度= 5.(现在)

This is what I have so far: 这是我到目前为止:

class ArbitraryArray{
public:
    int array[5];
    ArbitraryArray*subArray;

    ArbitraryArray(){}

    ArbitraryArray(int depth){
        if (depth == 2) subArray = new ArbitraryArray[5];
        else if (depth > 2) for (int i = 0; i < 5; i++) subArray = new ArbitraryArray(depth - 1);
    }
};

And I'd create a 2 dimensional object like so: 我会像这样创建一个二维对象:

ArbitraryArray testArray(2);

Or a 3 dimensional object like so: 或者像这样的三维物体:

ArbitraryArray testArray(3);

Problem is, when I tested it for depth = 3 and then tried to set an integer value, via: 问题是,当我测试深度= 3然后尝试设置整数值时,通过:

testArray.subArray[3].subArray[4].array[4] = 7;

I received a runtime error, leading me to believe that I'm doing something wrong in how I allocate these objects dynamically. 我收到了一个运行时错误,让我相信我在动态分配这些对象方面做错了。

Also, I included an empty default constructor since that gets called by lines like: 此外,我包含一个空的默认构造函数,因为它被以下行调用:

subArray = new ArbitraryArray[5];

I'm aware this may not be the best way to go about creating an arbitrary dimensional array data structure, but I'd really like to figure out why this implementation is not working before potentially looking for better methods. 我知道这可能不是创建任意维数组数据结构的最佳方法,但我真的想弄清楚为什么这个实现在寻找更好的方法之前不起作用。

Also I am aware I shouldn't have a line like: 另外我知道我不应该像以下一样:

int array[5];

And that it should be a pointer instead so that there isn't a ton of wasted memory allocation for all the levels of the array above the bottom dimension. 并且它应该是一个指针,以便在底部维度之上的阵列的所有级别上没有大量浪费的内存分配。 And I intend to modify it to that after I get this basic idea working. 在我得到这个基本想法之后,我打算将其修改为。

How about using std::vector for allocating the correct amount of blank memory, which would be 如何使用std :: vector分配正确数量的空白内存,这将是

sizeof(T) * dim1 * dim2 * dim3 * ...

Then write a helper class which takes care of the indexing, ie, it will compute i from given (x,y,z,...) , whatever many dimensions you might have. 然后编写一个辅助类来处理索引,即它将从给定的(x,y,z,...)计算i ,无论你有多少维度。

The beauty of this approach, IMHO, lies in not having to fiddle with pointers, and the helper class simply implements an indexing scheme of your preference ( row major or column major ). 恕我直言,这种方法的优点在于不必乱用指针,辅助类只是实现了你的偏好( 行主列专业 )的索引方案。

EDIT 编辑

When using std::valarray , things may become easier, as you can use std::slice and/or std::gslice to calculate your indexing for you. 当使用std :: valarray时 ,事情可能会变得更容易,因为您可以使用std :: slice和/或std :: gslice为您计算索引。

Well, for once, if depth is greater than 2, you create five ArbitraryArrays, but you save all their pointers in one SubArray pointer. 好吧,一次,如果depth大于2,则创建五个ArbitraryArrays,但是将所有指针保存在一个SubArray指针中。 SubArray needs to be an array of pointers to ArbitraryArrays, try ArbitraryArray *subArray[5]; SubArray需要是一个指向ArbitraryArrays的指针数组,试试ArbitraryArray *subArray[5]; and for (int i = 0; i < 5; i++) subArray[i] = new ArbitraryArray(depth - 1) and see what happens. 并且for (int i = 0; i < 5; i++) subArray[i] = new ArbitraryArray(depth - 1)并看看会发生什么。

Haven't compiled anything, just visual inspection. 没有编译任何东西,只是视觉检查。 What about this: 那这个呢:

template<int array_length>
class ArbitraryArray{
public:
    int array[array_length];
    ArbitraryArray ** subArray;

    ArbitraryArray(){}

    ArbitraryArray(int depth){
        if (depth == 1)
            subArray = 0;
        else {
            subArray = new ArbitraryArray*[array_length];
            for (int i = 0; i < array_length; i++)
                subArray[i] = new ArbitraryArray(depth - 1);
        }
    }
};

In your example you are creating an array that is all over the place in memory instead of one array that is stored in a continuous block of memory. 在您的示例中,您创建的数组遍布内存中的所有位置,而不是存储在连续内存块中的一个数组。 This could cause some issues depending on you handle the memory. 这可能会导致一些问题,具体取决于您处理内存。 eg using memcpy on it will never work. 例如,使用memcpy永远不会工作。

I think a little more flexible approach would be create one large array and instead have an index into the array based on the number of dimensions 我认为一种更灵活的方法是创建一个大型数组,而是根据维数创建一个数组索引

int n = static_cast<int>(pow( 5.0, static_cast<double>(depth) ));   
Type* a = new Type[ n ]; 

ie since you base your array size on 5, a 2-dim size would be 5x5 and a 3-dim 5x5x5 也就是说,因为你的数组大小是5,2-dim的大小是5x5和3-dim 5x5x5

to access an element in the array say a[2,2,3] (0-based) it could be calculated as 要访问数组中的元素,可以将其计算为[2,2,3](从0开始)

a[2*5*5 + 2*5 + 3] 

Just use the Boost multi_array class. 只需使用Boost multi_array类。 It is very flexible, efficient and can perform bounds checking. 它非常灵活,高效并且可以执行边界检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM