4

本当に使いやすい 2D グリッドを作成したいと考えています。グリッド内の各セルは、大量のデータを格納できる必要があります。理想的には、一度に 1 つのセルをトラバースし、任意のグリッド セルの直近のセルを取得できるようにしたいと考えています。

最初に考えたのは、Cell の隣接セル (合計 4 つ) へのポインターのベクトルを格納し、leftNeighbour、rightNeighbour などの便利な関数を作成することでした。初期化後にグリッドを接続します。

std::vector は動的にサイズ変更可能な配列であると想定されているため、ポインターの位置 (0 == 左、1 == 右など) のみをハードコーディングする場合、これはかなり不必要だと思います。ただし、セルの隣接セルを反復処理するためのより適切な方法が可能になります。私が考慮しなければならないもう1つのことは、セルがグリッドの端との境界にあるかどうかです(これをテストするか、これが起こらないようにグリッドを1セルだけ暗黙的に拡張するか)。

誰かがより良い代替案を提案できますか、またはこれは合理的な設計のように聞こえますか?

ありがとう、ダン

4

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

私はあなたが のこれを最初に考える方法で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];
};

これは反復可能であり (これは基準の 1 つです)、ネイバーを格納するために動的割り当てを使用しません。

于 2009-01-25T20:28:40.140 に答える