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