C++ iteratorlar


ULASHISH

C++ iteratorlar

Iteratorlar ma’lumotlar tuzilmalari (vektorlar, set’lar va h.k.) elementlarini "ko‘rsatish" orqali ularga murojaat qilish va ular bo‘ylab iteratsiya qilish (aylanib chiqish) uchun ishlatiladi.

U "iterator" deb ataladi, chunki "iteratsiya" — sikl yordamida aylanib chiqish uchun ishlatiladigan texnik atama.

Vektor bo‘ylab iteratsiya qilish uchun quyidagi misolga qarang:

Misol

// Create a vector called cars that will store strings vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Create a vector iterator called it vector<string>::iterator it; // Loop through the vector with the iterator for (it = cars.begin(); it != cars.end(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »

Misol izohi

  1. Avval turli avtomobil ishlab chiqaruvchilarining nomlarini saqlash uchun stringlardan iborat vektor yaratamiz.
  2. So‘ng vektor bo‘ylab aylanib chiqishda foydalanadigan it nomli "vektor iteratori"ni yaratamiz.
  3. Keyin iterator yordamida vektor bo‘ylab aylanib chiqish uchun for siklidan foydalanamiz. Iterator (it) vektordagi birinchi elementni (cars.begin()) ko‘rsatadi va sikl it qiymati cars.end() ga teng bo‘lmaguncha davom etadi.
  4. Inkrement operatori (++it) iteratorni vektordagi keyingi elementga suradi.
  5. Dereference operatori (*it) iterator ko‘rsatib turgan elementga murojaat qiladi.

Eslatma: Iteratorning tipi u aylanib chiqadigan ma’lumotlar tuzilmasining tipiga mos kelishi kerak (bizning misolimizda string)


begin() va end() nima?

begin() va end() — vektorlar va list’lar kabi ma’lumotlar tuzilmalariga tegishli funksiyalardir. Ular iteratorning o‘ziga tegishli emas. Aksincha, ular ushbu ma’lumotlar tuzilmalarining elementlariga murojaat qilish va ular bo‘ylab iteratsiya qilish uchun iteratorlar bilan birga ishlatiladi.

  • begin() ma’lumotlar tuzilmasining birinchi elementini ko‘rsatuvchi iteratorni qaytaradi.
  • end() oxirgi elementdan keyingi bitta pozitsiyani ko‘rsatuvchi iteratorni qaytaradi.

Ular qanday ishlashini tushunish uchun misol sifatida vektorlardan foydalanishda davom etamiz:

vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; vector<string>::iterator it;

begin() misollari

begin() vektordagi birinchi elementni (0-indeks, ya’ni "Volvo") ko‘rsatadi:

Misol

// Point to the first element in the vector it = cars.begin();
O‘zingiz sinab ko‘ring »

Ikkinchi elementni (BMW) ko‘rsatish uchun cars.begin() + 1 deb yozishingiz mumkin:

Misol

// Point to the second element it = cars.begin() + 1;
O‘zingiz sinab ko‘ring »

Va, albatta, bu uchinchi elementni cars.begin() + 2 bilan ko‘rsatish mumkinligini ham anglatadi:

Misol

// Point to the third element it = cars.begin() + 2;
O‘zingiz sinab ko‘ring »

end() misoli

end() vektordagi oxirgi elementdan keyingi bitta pozitsiyani ko‘rsatadi (ya’ni u haqiqiy elementni ko‘rsatmaydi, balki vektorning oxiri shu yerda ekanini bildiradi).

Demak, end() yordamida cars vektoridagi oxirgi elementni (Mazda) ko‘rsatish uchun cars.end() - 1 dan foydalanishingiz mumkin:

Misol

// Point to the last element it = cars.end() - 1;
O‘zingiz sinab ko‘ring »

Nega "ko‘rsatadi" deymiz?

Iteratorlar "ko‘rsatkichlar (pointers)"ga o‘xshaydi: ular ma’lumotlar tuzilmasidagi elementlardan qiymat qaytarmaydi, balki ularni "ko‘rsatadi". Ular muayyan pozitsiyaga ishora qiladi va kerak bo‘lganda qiymatning nusxasini olmasdan unga murojaat qilish hamda uni o‘zgartirish imkonini beradi. Masalan:

Misol

// Point to the first element in the vector it = cars.begin(); // Modify the value of the first element *it = "Tesla"; // Volvo is now Tesla
O‘zingiz sinab ko‘ring »

auto kalit so‘zi

C++ 11 va undan keyingi versiyalarda iteratorning tipini aniq e’lon qilib ko‘rsatish o‘rniga auto kalit so‘zidan foydalanishingiz mumkin.

auto kalit so‘zi kompilyatorga to‘g‘ri ma’lumot tipini avtomatik aniqlash imkonini beradi, bu esa kodni soddalashtiradi va uni o‘qishni osonlashtiradi:

Buning o‘rniga:

vector<string>::iterator it = cars.begin();

Shunchaki quyidagicha yozishingiz mumkin:

auto it = cars.begin();
O‘zingiz sinab ko‘ring »

Yuqoridagi misolda kompilyator it ning tipini cars.begin() qaytaradigan tipga, ya’ni vector<string>::iterator ga qarab aniqlaydi.

auto kalit so‘zi for sikllarida ham ishlaydi:

for (auto it = cars.begin(); it != cars.end(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »


for-each sikli va iteratorlar

Ma’lumotlar tuzilmasining elementlarini shunchaki aylanib chiqish uchun for-each siklidan quyidagicha foydalanishingiz mumkin:

Misol

// Create a vector called cars that will store strings vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Print vector elements for (string car : cars) {   cout << car << "\n"; }
O‘zingiz sinab ko‘ring »

Agar elementlarni faqat o‘qiyotgan bo‘lsangiz va ularni o‘zgartirish kerak bo‘lmasa, for-each sikli iteratorlarga qaraganda ancha sodda va tushunarli.

Biroq iteratsiya davomida elementlarni qo‘shish, o‘zgartirish yoki o‘chirish, teskari tartibda aylanib chiqish yoki ayrim elementlarni o‘tkazib yuborish kerak bo‘lsa, iteratorlardan foydalanishingiz kerak:

Misol

// Create a vector called cars that will store strings vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Loop through vector elements for (auto it = cars.begin(); it != cars.end(); ) {   if (*it == "BMW") {     it = cars.erase(it); // Remove the BMW element   } else {     ++it;   } } // Print vector elements for (const string& car : cars) {   cout << car << "\n"; }
O‘zingiz sinab ko‘ring »

Teskari tartibda aylanib chiqish

Teskari tartibda aylanib chiqish uchun begin() va end() o‘rniga rbegin() va rend() dan foydalanishingiz mumkin:

Misol

// Iterate in reverse order for (auto it = cars.rbegin(); it != cars.rend(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »

Boshqa ma’lumotlar tuzilmalarini aylanib chiqish

Iteratorlar kodni qayta ishlatish uchun juda qulay, chunki vektorlar, list’lar, deque’lar, set’lar va map’larni aylanib chiqishda bir xil sintaksisdan foydalanishingiz mumkin:

list misoli

// Create a list called cars that will store strings list<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Loop through the list with an iterator for (auto it = cars.begin(); it != cars.end(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »

deque misoli

// Create a deque called cars that will store strings deque<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Loop through the deque with an iterator for (auto it = cars.begin(); it != cars.end(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »

set misoli

// Create a set called cars that will store strings set<string> cars = {"Volvo", "BMW", "Ford", "Mazda"}; // Loop through the set with an iterator for (auto it = cars.begin(); it != cars.end(); ++it) {   cout << *it << "\n"; }
O‘zingiz sinab ko‘ring »

map misoli

// Create a map that will store strings and integers map<string, int> people = { {"John", 32}, {"Adele", 45}, {"Bo", 29} }; // Loop through the map with an iterator for (auto it = people.begin(); it != people.end(); ++it) {   cout << it->first << " is: " << it->second << "\n"; }
O‘zingiz sinab ko‘ring »

Iteratorlarni qo‘llab-quvvatlash

Yuqoridagi misollar iteratorlarni qo‘llab-quvvatlaydigan turli ma’lumotlar tuzilmalarini qanday aylanib chiqishni ko‘rsatadi (vector, list, deque, map va set iteratorlarni qo‘llab-quvvatlaydi, steklar va navbatlar esa qo‘llab-quvvatlamaydi).


Algoritmlar

Iteratorlarning yana bir muhim xususiyati shundaki, ular ma’lumotlar tuzilmasidagi elementlarni saralash va qidirish uchun sort() va find() kabi turli algoritm funksiyalari (<algorithm> kutubxonasida joylashgan) bilan birga ishlatiladi.

Masalan, sort() funksiyasi ma’lumotlar tuzilmasidagi elementlarni boshidan oxirigacha saralash uchun parametr sifatida iteratorlarni (odatda begin() va end() qaytaradigan) qabul qiladi.

Ushbu misolda elementlar string bo‘lgani uchun alifbo tartibida saralanadi:

Misol

#include <iostream> #include <vector> #include <algorithm>  // Include the <algorithm> library using namespace std; int main() {   // Create a vector called cars that will store strings   vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};   // Sort cars in alphabetical order   sort(cars.begin(), cars.end());   // Print cars in alphabetical order   for (string car : cars) {     cout << car << "\n";   }   return 0; }
O‘zingiz sinab ko‘ring »

Bu misolda esa elementlar butun son bo‘lgani uchun son qiymati bo‘yicha saralanadi:

Misol

#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() {   // Create a vector called numbers that will store integers   vector<int> numbers = {1, 7, 3, 5, 9, 2};   // Sort numbers numerically   sort(numbers.begin(), numbers.end());   for (int num : numbers) {     cout << num << "\n";   }   return 0; }
O‘zingiz sinab ko‘ring »

Tartibni teskarisiga o‘zgartirish uchun begin() va end() o‘rniga rbegin() va rend() dan foydalanishingiz mumkin:

Misol

#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() {   // Create a vector called numbers that will store integers   vector<int> numbers = {1, 7, 3, 5, 9, 2};   // Sort numbers numerically in reverse order   sort(numbers.rbegin(), numbers.rend());   for (int num : numbers) {     cout << num << "\n";   }   return 0; }
O‘zingiz sinab ko‘ring »



W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!