Heim >Backend-Entwicklung >C++ >Wie kann ich in C einen Flattening-Iterator erstellen, um die Iteration über verschachtelte Container zu vereinfachen?

Wie kann ich in C einen Flattening-Iterator erstellen, um die Iteration über verschachtelte Container zu vereinfachen?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-27 19:22:09275Durchsuche

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

Iteratoren in C reduzieren

Herkömmliche Iteratoren navigieren durch die Elemente eines einzelnen Containers, aber manchmal stoßen wir auf verschachtelte Container, bei denen jedes Element im äußeren Container ein separates Element darstellt Sammlung. Um alle Elemente nacheinander zu durchlaufen, benötigen wir einen Mechanismus zum „Abflachen“ der verschachtelten Struktur.

Hier kommen Flattening-Iteratoren ins Spiel. Sie kombinieren nahtlos mehrere Ebenen von Behältern und präsentieren sie als eine einzige zusammenhängende Sequenz. Man kann die abgeflachten Elemente mithilfe einer standardmäßigen bereichsbasierten Schleife durchlaufen, als ob sie alle in einem einzelnen Container enthalten wären.

Implementierung

Es gibt zwar keine integrierte Implementierung in Für die wichtigsten C-Bibliotheken kann eine Beispielimplementierung erstellt werden:

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

Um diesen Flattening-Iterator zu verwenden, können wir die Flatten-Funktion nutzen Vorlage:

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

Beispielverwendung

Betrachten Sie diesen verschachtelten Container:

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

Durch die Verwendung des Flattening-Iterators können wir nahtlos über alle Zahlen iterieren:

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

Fazit

Flattening-Iteratoren bieten eine effiziente und elegante Methode zum linearen Durchqueren verschachtelter Container. Dieser Ansatz macht komplexe verschachtelte Schleifen oder manuelle Indexverwaltung überflüssig. Obwohl diese Implementierung nicht Teil der Standardbibliothek ist, kann sie problemlos in Ihre Codebasis integriert werden, um die Flexibilität zu erhöhen und die Lesbarkeit zu verbessern.

Das obige ist der detaillierte Inhalt vonWie kann ich in C einen Flattening-Iterator erstellen, um die Iteration über verschachtelte Container zu vereinfachen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn