如何在C ++中创建高效的2D网格?

时间:2009-01-25 20:03:41

标签: c++ stl vector

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

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

std :: vector应该是一个动态可调整大小的数组,所以如果我只想对指针的位置进行硬编码(0 == left,1 == right,等等)。但是,它确实允许更好的方式迭代单元的邻居。我必须考虑的另一件事是,如果单元格位于与网格边缘的边界上(无论是为了测试还是只是将网格隐藏地扩展一个单元格,以便永远不会发生这种情况)。

任何人都可以提出更好的选择,或者这听起来像是一个合理的设计吗?

谢谢,Dan

4 个答案:

答案 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];
};

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