59 / 90

C++ std::deque

C++ std::deque (Ikki tomonlama navbat)

C++ da STL deque ketma-ket konteyner bo'lib, ikki tomonlama navbat ma'lumotlar strukturasining funksionalligini ta'minlaydi.

Muntazam navbatda elementlar orqa tomondan qo'shiladi va old tomondan chiqariladi. Biroq, dequeda biz old va orqa qismlarga elementlarni kiritishimiz va olib tashlashimiz mumkin.

Deque Data Structure

In a deque, we can insert and remove elements from both the front and rear.

To learn more about deques, visit Deque Data Structure.

C++ STL Deque yarating

C++ da deque yaratish uchun avval deque sarlavha faylini kiritishimiz kerak.

example.cpp
#include <deque>

Ushbu faylni import qilgandan so'ng, biz quyidagi sintaksis yordamida deque yaratishimiz mumkin:

example.cpp
deque<type> dq;

Bu erda type biz dequeda saqlamoqchi bo'lgan ma'lumotlar turini ko'rsatadi. Masalan,

example.cpp
// butun sonli ma'lumotlar turini yarating
deque<int> dq_integer;

// string ma'lumotlar turini yarating
deque<string> dq_string;

Dequeni ishga tushiring

Biz C++ deque-ni quyidagi usullar bilan ishga tushirishimiz mumkin:

example.cpp
// 1-usul: ishga tushirish ro'yxati
deque<int> deque1 = {1, 2, 3, 4, 5};

// 2-usul: bir xil ishga tushirish
deque<int> deque2 {1, 2, 3, 4, 5};

Bu erda deque1 ham, deque2 ham 1, 2, 3, 4, 5 qiymatlari bilan ishga tushiriladi.

Misol: C++ Deque

example.cpp
#include <iostream>
#include <deque>
using namespace std;

// funksiya prototipi
void display_deque(deque<int>);

int main() {
 
  // yagona ishga tushirish
  deque<int> deque1 {1, 2, 3, 4, 5};

  cout << "deque1 = ";

  // deque1 ning ko'rsatish elementlari
  for (int num : deque1) {
    cout << num << ", ";
  }

  return 0;
}

Chiqish

kod
deque1 = 1, 2, 3, 4, 5,

Yuqoridagi misolda biz bir xil ishga tushirish yordamida deque1 nomli dequeni e'lon qildik va ishga tushirdik.

example.cpp
deque<int> deque1 {1, 2, 3, 4, 5};

Keyin, biz ranged for loop yordamida deque tarkibini ko'rsatdik.

example.cpp
for (int num : deque1) {
  cout << num << ", ";
}

C++ Deque yaratishning boshqa usullari Fill Constructor Method yordamida biz uning hajmi va elementini belgilash orqali dequeni ishga tushirishimiz mumkin. Misol uchun, // to'ldiruvchi konstruktor deque<int> deque1(5, 12); Bu yerda biz 12 qiymatli 5 o‘lchamli dekani ishga tushirdik. Bu deque<int> deque1 = {12, 12, 12, 12, 12}; ga ekvivalent. Barcha elementlar bir xil qiymatga ega ekanligiga e’tibor bering. Biz boshqa dequedan elementlarni nusxalash orqali dequeni ishga tushirishimiz mumkin. Bu diapazon usuli sifatida tanilgan. Biz diapazon usulini ishga tushirish yordamida bir dequeni boshqasiga nusxalashimiz mumkin. deque<int> deque1 = {1, 2, 3, 4, 5}; // copy all elemnts of deque1 to deque2 deque<int> deque2(deque1.begin(), deque1.end()); Bu yerda biz birinchi navbatda deque1 nomli deque yaratdik. Keyin, biz deque1 ning barcha elementlarini nusxalash orqali deque2 deb nomlangan boshqa deque yaratdik. Biz nusxa olmoqchi bo'lgan elementlar oralig'ini ham belgilashimiz mumkin. Masalan, // deque1 deque<int> deque3(deque1.begin() + 1, deque1.begin() + 3 ning 1 indeksidan 2 indeksiga elementlarni nusxalash; Bu erda boshlang'ich nuqtasi deque1.begin() + 1 bo'lib, u deque1 ning 1 indeksiga ishora qiladi. Yakuniy nuqta deque1.begin() + 3 bo'lib, u indeks 3 ga ishora qiladi. Biroq, deque3 {2, 3} bo'ladi, chunki oxirgi nuqta eksklyuziv, ya'ni oxirgi nuqta ko'chirilmaydi.

C++ Deque usullari

C++ tilida deque klassi dequeda turli operatsiyalarni bajarish uchun turli usullarni taqdim etadi.

Usullar tavsifi push_back() elementni orqaga qo'yadi push_front() elementni old qismiga qo'yadi pop_back() elementni orqadan olib tashlaydi pop_front() elementni old tomondan olib tashlaydi front() oldingi elementni qaytaradi back() orqadagi elementni qaytaradi at() XCODEXning ko'rsatilgan indeksidagi elementni o'rnatadi/qaytaradi XCODEX ning XCODEX raqamlarini qaytarsa, XCODEX ning XCODEX raqamlarini qaytarsa. deque bo'sh

Dequega elementlarni kiritish

Elementlarni kiritish uchun quyidagi usullardan foydalanishimiz mumkin:

-push_back() - oxirida elementlarni kiritish -push_front() - elementlarni boshida kiritish

Masalan,

example.cpp
#include <iostream>
#include <deque>
using namespace std;

int main() {

  deque<int> nums {2, 3};

  cout << "Initial Deque: ";
  for (const int& num : nums) {
    cout << num << ", ";
  }
  
  // orqa tomonda butun son 4 qo'shing
  nums.push_back(4);
   
  // old tomoniga butun son 1 qo'shing
  nums.push_front(1);
  
  cout << "\nFinal Deque: ";
  for (const int& num : nums) {
    cout << num << ", ";
  }
  
  return 0;
}

Chiqish

kod
Initial Deque: 2, 3, 
Final Deque: 1, 2, 3, 4,

Yuqoridagi misolda biz deque 2 va 3 elementlari bilan nums nomli butun sonlarni ishga tushirdik.

Keyin, biz 4-sonni raqamlarning orqa tomoniga qo'ydik.

example.cpp
// raqamlar = {2, 3, 4}
nums.push_back(4);

Nihoyat, biz deque old tomoniga 1 qo'shdik.

example.cpp
// raqamlar = {1, 2, 3, 4}
nums.push_front(1);

[!NOTE] Dequega elementlar qo'shish uchun insert() va emplace() usullaridan ham foydalanishimiz mumkin.

Deque dan elementlarga kirish

deque elementlariga kirish uchun quyidagi usullardan foydalanishimiz mumkin:

-front() - oldingi elementni qaytaradi -back() - orqadagi elementni qaytaradi -at() - belgilangan indeksdagi elementni qaytaradi

Masalan,

example.cpp
#include <iostream>
#include <deque>
using namespace std;

int main() {

  deque<int> nums {1, 2, 3};
  
  cout << "Front element: " << nums.front() << endl;
  cout << "Back element: " << nums.back() << endl;
  cout << "Element at index 1: " << nums.at(1) << endl;
  cout << "Element at index 0: " << nums[0];
  
  return 0;
}

Chiqish

kod
Front element: 1
Back element: 3
Element at index 1: 2
Element at index 0: 1

Yuqoridagi misolda,

-nums.front() - deque old qismidagi elementni qaytaradi, ya'ni 1 -nums.back() - dequening orqa qismidagi elementni qaytaradi, ya'ni 3 -nums.at(1) - 1-indeksdagi elementni, ya'ni 2-ni qaytaradi -nums[0] - 0 indeksidagi elementni qaytaradi, ya'ni 1

[!NOTE] Deque elementlariga kirish uchun [] operatoridan foydalanishimiz mumkin bo'lsa-da, at() usulidan foydalanish afzalroqdir. Buning sababi, at() deque chegaradan tashqarida bo'lganda istisno qiladi, [] esa axlat qiymatini beradi.

Deque elementlarini o'zgartirish

deque elementini o'zgartirish uchun at() usulidan foydalanishimiz mumkin. Masalan,

example.cpp
#include <iostream>
#include <deque>
using namespace std;

int main() {

  deque<int> nums = {1, 2};
  
  cout << "Initial Deque: ";

  for (const int& num : nums) {
    cout << num << ", ";
  }
  
  // indeksdagi elementlarni o'zgartirish
  nums.at(0) = 3;
  nums.at(1) = 4;
  
  cout << "\nUpdated Deque: ";

  for (const int& num : nums) {
    cout << num << ", ";
  }
  
  return 0;
}

Chiqish

kod
Initial Deque: 1, 2,    
Updated Deque: 3, 4,

Yuqoridagi misolda nums deque ning dastlabki tarkibi {1, 2} dir.

Keyin, biz belgilangan indekslardagi elementlarni o'zgartirish uchun at() usulidan foydalandik:

-nums.at(0) = 2; - 0 indeksidagi qiymatni 3 ga o'zgartiradi -nums.at(1) = 4; - indeks qiymatini 1 dan 4 gacha o'zgartiradi

Dequedan elementlarni olib tashlang

Quyidagi usullar yordamida deque elementlarini olib tashlashimiz mumkin:

-pop_back() - elementni orqa tomondan olib tashlaydi -pop_front() - elementni old tomondan olib tashlaydi

Masalan,

example.cpp
#include <iostream>
#include <deque>
using namespace std;

// display_deque() funksiyasi prototipi
void display_deque(deque<int>);

int main() {

  deque<int> nums {1, 2, 3};
  
  cout << "Initial Deque: ";
  display_deque(nums);

  // elementni orqa tomondan olib tashlang
  nums.pop_back();
  
  cout << "\nDeque after pop_back(): ";
  display_deque(nums);
  
  // elementni old tomondan olib tashlang
  nums.pop_front();
  
  cout << "\nDeque after pop_front(): ";
  display_deque(nums);
  
  return 0;
}

// deque elementlarini chop etish uchun yordamchi funksiya
void display_deque(deque<int> dq){
  for (const int& num : dq) {
    cout << num << ", ";
  }
}

Chiqish

kod
Initial Deque: 1,  2,  3,  
Deque after pop_back(): 1, 2, 
Deque after pop_front(): 2,

Yuqoridagi misolda biz {1, 2, 3} elementlari bilan nums nomli deque butun sonini ishga tushirdik.

Keyin raqamlardan elementlarni olib tashlash uchun pop_back() va pop_front() dan foydalandik.

example.cpp
nums.pop_back(); // olib tashlaydi 3
names.pop_front(); // olib tashlaydi 1

Shunday qilib, yakuniy deque {2} bo'ladi.

C++ Deque iteratorlari

Iteratorlar deque elementining xotira manziliga ishora qilish uchun ishlatilishi mumkin.

Biz quyidagi sintaksis yordamida deque iteratorini yaratishimiz mumkin:

example.cpp
deque<type>::iterator itertaor_name;

Masalan,

example.cpp
// int deque uchun iterator
deque<int>::iterator iter_int;

// 
deque<double>::iterator iter_double;

Deque iteratorlari yordamida elementlarga kirish

Biz iteratorlar yordamida deque -dagi elementlarga kirishimiz mumkin. Masalan,

example.cpp
#include <iostream>
#include <deque>
using namespace std;

int main() {

  deque<int> nums {1, 2, 3};
  
  // deque uchun iteratorni e'lon qiling
 deque<int>::iterator dq_iter;
  
  // iteratorni birinchi elementga ko'rsating
  dq_iter = nums.begin();
  
  // * yordamida itertor tomonidan ko'rsatilgan chop etish qiymati
  int first_element = *dq_iter; 

  cout << "nums[0] = " << first_element << endl;
  
  // iteratorni 1-indeksdagi elementga ko'rsating
  dq_iter = nums.begin() + 1; 
  int element_index1 = *dq_iter; 

  cout << "nums[1] = " << element_index1 << endl;

  // iterator nuqtasini oxirgi elementga aylantiring
  dq_iter = nums.end() - 1; 
  int last_element = *dq_iter; 

  cout << "nums[2] = " << last_element;
  
  return 0;
}

Chiqish

kod
nums[0] = 1
nums[1] = 2
nums[2] = 3

Yuqoridagi misolda biz deque dagi elementlarga kirish uchun iteratorlardan foydalanganmiz. Dastlab, biz deque tamsayıga ishora qiladigan iterator yaratdik:

example.cpp
deque<int>::iterator dq_iter;

Keyin, biz quyidagi elementlarga ishora qilish uchun dq_iter iteratoridan foydalandik:

  1. Birinchi element
example.cpp
dq_iter = nums.begin();

Bu erda begin() usuli birinchi elementga ishora qiluvchi iteratorni qaytaradi.

  1. 1-indeksdagi element
example.cpp
dq_iter = nums.begin() + 1;

begin() + 1 kodi 1-indeksdagi elementga ishora qiluvchi iteratorni qaytaradi.

[!NOTE] Umumlashtirish uchun nums.begin() + i i indeksidagi elementga ishora qiladi.

  1. Oxirgi element
example.cpp
dq_iter = nums.end() - 1;

E'tibor bering, biz nums.end() o'rniga nums.end() - 1 dan foydalanmoqdamiz.

Buning sababi, end() usuli iteratori oxirgi elementdan o'tgan iteratorga ishora qiladi. Shunday qilib, yakuniy elementni olish uchun biz 1 ni ayiramiz.

  1. Element qiymatini oling

Muayyan elementga ishora qilish uchun dq_iter dan foydalangandan so'ng, biz ushbu elementning qiymatini olish uchun * bilvosita operatoridan foydalanamiz:

example.cpp
// birinchi elementga ishora qiling
dq_iter = nums.begin();

// 1 qaytaradi
int first_element = *dq_iter;

Bu yerda *dq_iter dq_iter iteratori ko'rsatgan element qiymatini beradi.

Tez-tez so'raladigan savollar erase() usuli yordamida ko'rsatilgan indeksdagi elementni olib tashlashimiz mumkin. Masalan, deque<int> nums {1, 2, 3, 4, 5}; // removes element at index 1 // nums becomes {1, 3, 4, 5} nums.erase(nums.begin() + 1); Yuqoridagi kod 1-indeksdagi elementni nums dequedan olib tashlaydi. Shunday qilib, biz istalgan indeksdagi elementni quyidagi yordamida o'chirib tashlashimiz mumkin: nums.erase(nums.begin() + index); Biz bu erda ham erase() usulidan foydalanishimiz mumkin. #include <iostream> #include <deque> using namespace std; int main() { deque<int> nums {1, 2, 3, 4, 5}; // removes elements from index 1 to 2 nums.erase(nums.begin() + 1, nums.begin() + 3); for(auto num: nums) { cout << num << ", "; } return 0; } Chiqish 1, 4, 5, Dastlab, nums {1, 2, 3, 4, 5} elementlarini o'z ichiga oladi. Keyin 1-indeksdan 2-indeksgacha boʻlgan elementlarni nums.erase(nums.begin() + 1, nums.begin() + 3); yordamida olib tashlaymiz. Eʼtibor bering, diapazonning oxirgi nuqtasi nums.begin() + 3 , lekin 3-indeksdagi element oʻchirilmaydi. Buning sababi, erase() funksiyasining so'nggi nuqtasi eksklyuzivdir. Dequening barcha elementlarini o'chirish uchun clear() usulidan foydalanishimiz mumkin. deque<int> nums {1, 2, 3}; // clear all the elements nums.clear(); Dequedagi elementlar sonini topish uchun size() usulidan foydalanishimiz mumkin. deque<int> nums {1, 2}; // returns 2 cout << nums.size(); empty() usuli yordamida deque bo'sh yoki yo'qligini ham aniqlashimiz mumkin: // false coutni qaytaradi << nums.empty(); Ha, biz deque iteratorini ishga tushirish uchun auto kalit so'zidan foydalanishimiz mumkin. Biroq, biz auto dan iteratorni ishga tushirmasdan oddiygina e'lon qilish uchun foydalana olmaymiz. Misol uchun, bizda nums deb nomlangan int deque bor deylik. Keyin quyidagi auto dq_iter = nums.begin(); kodi deque<int>::iterator dq_iter = nums.begin(); ga ekvivalent bo'ladi Biroq, quyidagi kod noto'g'ri: auto dq_iter; // invalid Buning sababi, biz dq_iterni ishga tushirmaganmiz. Natijada, C++ uning turini aniqlay olmaydi, shuning uchun xatolik yuzaga keladi.