Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Saya Boleh Mencipta Iterator Meratakan dalam C untuk Memudahkan Lelaran Ke Atas Bekas Bersarang?
Pelajar konvensional menavigasi unsur-unsur bekas tunggal, tetapi kadangkala kita menemui bekas bersarang, di mana setiap elemen dalam bekas luar mewakili satu yang berasingan koleksi. Untuk merentasi semua elemen secara berurutan, kita memerlukan mekanisme untuk "meratakan" struktur bersarang.
Di sinilah iterator meratakan memainkan peranan. Ia menggabungkan berbilang peringkat bekas dengan lancar, mempersembahkannya sebagai urutan padu tunggal. Seseorang boleh mengulangi elemen yang diratakan menggunakan gelung berasaskan julat standard, seolah-olah semuanya terkandung dalam bekas tunggal.
Walaupun tiada pelaksanaan terbina dalam dalam perpustakaan C utama, satu contoh pelaksanaan boleh dibuat:
#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_; };
Untuk menggunakan lelaran merata ini, kita boleh memanfaatkan kaedah meratakan templat fungsi:
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); }
Pertimbangkan bekas bersarang ini:
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 });
Dengan menggunakan lelaran merata, kami boleh mengulangi semua nombor dengan lancar:
for (auto it(flatten(s.begin(), s.end())); it != s.end(); ++it) { std::cout << *it << endl; // prints 1, 2, 3, ..., 12 }
Meratakan iterator menyediakan kaedah yang cekap dan elegan untuk melintasi bekas bersarang secara linear. Pendekatan ini menghapuskan keperluan untuk gelung bersarang yang kompleks atau pengurusan indeks manual. Walaupun bukan sebahagian daripada pustaka standard, pelaksanaan ini boleh dengan mudah dimasukkan ke dalam pangkalan kod anda untuk meningkatkan fleksibiliti dan meningkatkan kebolehbacaan.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mencipta Iterator Meratakan dalam C untuk Memudahkan Lelaran Ke Atas Bekas Bersarang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!