在C++中将列表转换为二维对象数组
Convert list into two dimensional array of objects in C++
我有一个这样的列表:
list<Box*> list;
其中 Box 是包含 x 和 y 值的对象。
box->getX();
box->getY();
我需要做的是将其转换为二维数组(或向量的向量),其中:
array[x][y] == box;
我还需要将空对象或空对象放入此数组,即:位置 4,6 没有任何内容(或空对象)。
我的想法:
Box** boxes = new Box*[rows];
for(int r=0;r<rows;r++)
boxes[r] = new Box[columns];
for(Box *b : list){
boxes[b->x][b->y] = b;
}
但这给了我一个错误:没有可行的重载 =;
另一点:我需要与列表具有相同的指针,而不是那些项目的副本。
b
是一个Box*
,但是因为boxes
是一个Box**
,所以boxes[b->x][b-y]
只是一个Box
。所以你有类型不匹配 - 你试图将 Box*
分配给 Box
,因此出现错误。
如果你想使 boxes
成为 Box*
的二维数组,你只需要另一个 *
:
Box*** boxes = new Box**[rows];
for(int r=0;r<rows;r++) {
boxes[r] = new Box*[columns];
}
现在这将起作用:
for (Box *b : list){
boxes[b->x][b->y] = b;
}
我假设 x
和 y
是 Box
位于给定坐标 space 内的坐标。如果是这样,它们就不太适合 array/vector 索引。您必须分配 array/vector 来说明所有可能的坐标,即使是那些不包含 Box
的坐标。因此,我建议改用 std::map
,例如:
std::list<Box*> BoxList;
std::map<int, std::map<int, Box*> > BoxMap;
...
for (std::list<Box*>::iterator iter = BoxList.begin(); iter != BoxList.end(); ++iter)
{
Box *box = *iter;
BoxMap[box->getX()][box->getY()] = box;
}
您仍然可以获得所需的 array[x][y]
语法的好处,但您使用的内存要少得多(与您拥有的 Box
对象的实际数量成正比),并且如果您尝试访问Box
在给定的 x/y 坐标处,其中不存在 Box
,您将返回一个 NULL 指针,您可以测试它:
Box *box = BoxMap[x][y];
if (box) ...
这是一个使用向量的向量的解决方案:
#include <vector>
#include <list>
struct Box
{
int x;
int y;
};
typedef std::vector<Box*> BoxVector;
typedef std::vector<BoxVector> BoxVector2D;
int main()
{
std::list<Box*> lBoxes;
BoxVector2D boxes;
// fill lBoxes as needed...
for(Box *b : lBoxes)
{
boxes.resize(b->x+1);
boxes[b->x].resize(b->y + 1);
boxes[b->x][b->y] = b;
}
// use boxes as needed...
}
现在,正如其他评论所建议的那样,我假设坐标 space 是合理的。请注意,我们 resize
每个项目的矢量,确保我们不会越界。
至于 resize
-- 如果容量大于调整大小,vector::resize
基本上是无操作。因此,resize
仅在 b->x + 1
或 b->y + 1
超过当前矢量的容量时才起作用。
我有一个这样的列表:
list<Box*> list;
其中 Box 是包含 x 和 y 值的对象。
box->getX();
box->getY();
我需要做的是将其转换为二维数组(或向量的向量),其中:
array[x][y] == box;
我还需要将空对象或空对象放入此数组,即:位置 4,6 没有任何内容(或空对象)。
我的想法:
Box** boxes = new Box*[rows];
for(int r=0;r<rows;r++)
boxes[r] = new Box[columns];
for(Box *b : list){
boxes[b->x][b->y] = b;
}
但这给了我一个错误:没有可行的重载 =;
另一点:我需要与列表具有相同的指针,而不是那些项目的副本。
b
是一个Box*
,但是因为boxes
是一个Box**
,所以boxes[b->x][b-y]
只是一个Box
。所以你有类型不匹配 - 你试图将 Box*
分配给 Box
,因此出现错误。
如果你想使 boxes
成为 Box*
的二维数组,你只需要另一个 *
:
Box*** boxes = new Box**[rows];
for(int r=0;r<rows;r++) {
boxes[r] = new Box*[columns];
}
现在这将起作用:
for (Box *b : list){
boxes[b->x][b->y] = b;
}
我假设 x
和 y
是 Box
位于给定坐标 space 内的坐标。如果是这样,它们就不太适合 array/vector 索引。您必须分配 array/vector 来说明所有可能的坐标,即使是那些不包含 Box
的坐标。因此,我建议改用 std::map
,例如:
std::list<Box*> BoxList;
std::map<int, std::map<int, Box*> > BoxMap;
...
for (std::list<Box*>::iterator iter = BoxList.begin(); iter != BoxList.end(); ++iter)
{
Box *box = *iter;
BoxMap[box->getX()][box->getY()] = box;
}
您仍然可以获得所需的 array[x][y]
语法的好处,但您使用的内存要少得多(与您拥有的 Box
对象的实际数量成正比),并且如果您尝试访问Box
在给定的 x/y 坐标处,其中不存在 Box
,您将返回一个 NULL 指针,您可以测试它:
Box *box = BoxMap[x][y];
if (box) ...
这是一个使用向量的向量的解决方案:
#include <vector>
#include <list>
struct Box
{
int x;
int y;
};
typedef std::vector<Box*> BoxVector;
typedef std::vector<BoxVector> BoxVector2D;
int main()
{
std::list<Box*> lBoxes;
BoxVector2D boxes;
// fill lBoxes as needed...
for(Box *b : lBoxes)
{
boxes.resize(b->x+1);
boxes[b->x].resize(b->y + 1);
boxes[b->x][b->y] = b;
}
// use boxes as needed...
}
现在,正如其他评论所建议的那样,我假设坐标 space 是合理的。请注意,我们 resize
每个项目的矢量,确保我们不会越界。
至于 resize
-- 如果容量大于调整大小,vector::resize
基本上是无操作。因此,resize
仅在 b->x + 1
或 b->y + 1
超过当前矢量的容量时才起作用。