4

我想创建一个非常易于使用的 2D 网格。网格中的每个单元格都需要能够存储大量数据。理想情况下,我希望能够一次遍历一个网格,并获得任何网格单元的直接邻居。

我的第一个想法是存储一个指向 Cell 邻居(总共 4 个)的指针向量,然后为 leftNeighbour、rightNeighbour 等创建便利函数。在初始化后连接网格。

std::vector 应该是一个动态可调整大小的数组,所以如果我只想硬编码指针的位置(0 == 左,1 == 右等),这让我觉得没有必要。但是,它确实允许以更好的方式遍历单元格的邻居。我必须考虑的另一件事是该单元格是否位于网格边缘的边界上(是否对此进行测试或只是隐式地将网格扩展一个单元格,这样就不会发生这种情况)。

谁能提出一个更好的选择,或者这听起来像一个合理的设计?

谢谢,丹

4

4 回答 4

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;
        };
};

您可能想检测是否碰到了网格的边缘,除其他外,这将必须实施。

于 2009-01-25T20:57:49.287 回答
3

我会选择 Boost.MultiArray

于 2009-01-25T20:18:52.720 回答
1

看看GIL,它是一个通用的图像处理库。除其他外,它具有用于迭代图像的 2D 迭代器,并且非常通用,您也可以直接将其用于您的东西。至少值得一看如何实现这一点。

于 2009-01-25T21:28:48.210 回答
0

我假设您不想要 I-would-think-of-this-first 方法std::vector<std::vector<T> >,而是需要允许更复杂结构的方法。

在这种情况下,为什么不创建一个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];
};

这是可迭代的(这是您的标准之一)并且不使用动态分配来存储邻居。

于 2009-01-25T20:28:40.140 回答