我想创建一个非常易于使用的2D网格。网格中的每个单元都需要能够存储大量数据。理想情况下,我希望能够一次遍历网格一个单元格,并获得任何网格单元的直接邻居。
我的第一个想法是存储指向Cell邻居的指针向量(总共4个),然后为leftNeighbour,rightNeighbour等创建便利函数。等。初始化后连接网格。
std :: vector应该是一个动态可调整大小的数组,所以如果我只想对指针的位置进行硬编码(0 == left,1 == right,等等)。但是,它确实允许更好的方式迭代单元的邻居。我必须考虑的另一件事是,如果单元格位于与网格边缘的边界上(无论是为了测试还是只是将网格隐藏地扩展一个单元格,以便永远不会发生这种情况)。
任何人都可以提出更好的选择,或者这听起来像是一个合理的设计吗?
谢谢,Dan
答案 0 :(得分:4)
如果你想要一个四向迭代器,那就自己创建:
template<typename T, int width, int height>
class Grid {
public:
T data[width * height];
iterator begin() {
return iterator(data);
}
iterator end() {
return iterator(data + width * height);
}
class iterator {
public:
iterator(const iterator &other) :
ptr(other.ptr)
{
}
iterator &left() const {
return iterator(ptr - 1);
}
iterator &right() const {
return iterator(ptr + 1);
}
iterator &up() const {
return iterator(ptr - width);
}
iterator &down() const {
return iterator(ptr + width);
}
iterator &operator++() {
++ptr;
return *this;
}
iterator &operator--() {
--ptr;
return *this;
}
iterator operator++(int) {
++*this;
return iterator(ptr + 1);
}
iterator operator--(int) {
--*this;
return iterator(ptr - 1);
}
T operator*() const {
return *ptr;
}
private:
iterator();
iterator(T *ptr_) :
ptr(ptr_)
{
}
T *ptr;
friend class Grid;
};
};
您可能想要检测是否到达了网格的边缘,以及必须实施的那些。
答案 1 :(得分:3)
我会选择Boost.MultiArray
答案 2 :(得分:1)
查看GIL,这是一个通用的图像处理库。除此之外,它还有用于迭代图像的2D迭代器,并且非常通用,您也可以直接将它用于您的东西。至少值得一看,如何实现这一点。
答案 3 :(得分:0)
我假设你不想要std::vector<std::vector<T> >
的I-would-think-of-first方法,而是需要更复杂的结构。
在这种情况下,为什么不制作Node
类(或结构):
template<typename T>
class Node {
public:
typedef Node<T> *iterator;
// and const_iterator
T data;
Node(T data_ = T()) :
data(data_)
{
}
Node<T> *&left() {
return neighbors[0];
}
// etc.
iterator begin() {
return neighbors;
}
iterator end() {
return neighbors + 4;
}
private:
Node<T> *neighbors[4];
};
这是可迭代的(这是您的标准之一),并且不使用动态分配来存储邻居。