ホームページ  >  記事  >  バックエンド開発  >  C でフラット化イテレーターを作成して、ネストされたコンテナーの反復を簡素化するにはどうすればよいですか?

C でフラット化イテレーターを作成して、ネストされたコンテナーの反復を簡素化するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-27 19:22:09253ブラウズ

How Can I Create a Flattening Iterator in C   to Simplify Iteration Over Nested Containers?

C のイテレータのフラット化

従来のイテレータは、単一のコンテナの要素間を移動しますが、場合によっては、外側のコンテナの各要素が個別の要素を表すネストされたコンテナに遭遇することがあります。コレクション。すべての要素を順番に走査するには、ネストされた構造を「フラット化」するメカニズムが必要です。

ここでフラット化イテレータが登場します。複数のレベルのコンテナをシームレスに結合し、単一のまとまりのあるシーケンスとして表示します。標準の範囲ベースのループを使用して、あたかもそれらがすべて単一のコンテナーに含まれているかのように、フラット化された要素を反復処理できます。

実装

ただし、組み込みの実装はありません。主要な C ライブラリを使用して、実装例を作成できます。

#include <iterator>

template <typename OuterIterator>
class flattening_iterator {
public:
    using outer_iterator = OuterIterator;
    using inner_iterator = typename OuterIterator::value_type::iterator;

    using iterator_category = std::forward_iterator_tag;
    using value_type = typename inner_iterator::value_type;

    flattening_iterator() {}
    flattening_iterator(outer_iterator it) : outer_it_(it), outer_end_(it) {}
    flattening_iterator(outer_iterator it, outer_iterator end)
        : outer_it_(it), outer_end_(end) {
        if (outer_it_ == outer_end_) return;
        inner_it_ = outer_it_->begin();
        advance_past_empty_inner_containers();
    }

    reference operator*() const { return *inner_it_; }
    pointer operator->() const { return &*inner_it_; }

    flattening_iterator& operator++() {
        ++inner_it_;
        if (inner_it_ == outer_it_->end()) advance_past_empty_inner_containers();
        return *this;
    }

    flattening_iterator operator++(int) {
        flattening_iterator it(*this);
        ++*this;
        return it;
    }

    friend bool operator==(const flattening_iterator& a, const flattening_iterator& b) {
        if (a.outer_it_ != b.outer_it_) return false;
        if (a.outer_it_ != a.outer_end_ && b.outer_it_ != b.outer_end_ &&
            a.inner_it_ != b.inner_it_)
            return false;
        return true;
    }

    friend bool operator!=(const flattening_iterator& a, const flattening_iterator& b) {
        return !(a == b);
    }

private:
    void advance_past_empty_inner_containers() {
        while (outer_it_ != outer_end_ && inner_it_ == outer_it_->end()) {
            ++outer_it_;
            if (outer_it_ != outer_end_) inner_it_ = outer_it_->begin();
        }
    }

    outer_iterator outer_it_;
    outer_iterator outer_end_;
    inner_iterator inner_it_;
};

この平坦化イテレータを使用するには、 flatten 関数テンプレート:

template <typename Iterator>
flattening_iterator<Iterator> flatten(Iterator it) {
    return flattening_iterator<Iterator>(it, it);
}

template <typename Iterator>
flattening_iterator<Iterator> flatten(Iterator first, Iterator last) {
    return flattening_iterator<Iterator>(first, last);
}

使用例

次のネストされたコンテナについて考えてみましょう:

std::unordered_set<std::vector<int>> s;
s.insert(std::vector<int>());
s.insert({ 1, 2, 3, 4, 5 });
s.insert({ 6, 7, 8 });
s.insert({ 9, 10, 11, 12 });

フラット化反復子を利用することで、すべての関数をシームレスに反復できます。数値:

for (auto it(flatten(s.begin(), s.end())); it != s.end(); ++it) {
    std::cout << *it << endl;  // prints 1, 2, 3, ..., 12
}

結論

フラット化イテレータは、ネストされたコンテナを線形に走査するための効率的かつエレガントな方法を提供します。このアプローチにより、複雑なネストされたループや手動のインデックス管理が不要になります。この実装は標準ライブラリの一部ではありませんが、コードベースに簡単に組み込んで柔軟性を高め、読みやすさを向上させることができます。

以上がC でフラット化イテレーターを作成して、ネストされたコンテナーの反復を簡素化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。