65 / 90

C++ std::unordered_map

C++ std::unordered_map (Hash xarita)

C++ tilida STL unordered_map unordered associative container bo'lib, tartibsiz xarita yoki lug'at ma'lumotlar strukturasi funksiyalarini ta'minlaydi.

Oddiy xaritadan farqli o'laroq, tartibsiz xaritadagi kalitlarning tartibi aniqlanmagan.

Bundan tashqari, tartibsiz xarita hash table ma'lumotlar strukturasi sifatida amalga oshiriladi, oddiy xarita esa binary search tree ma'lumotlar tuzilmasi.

C++ STL unordered_map yarating

C++ da tartibsiz xarita yaratish uchun avval unordered_map sarlavha faylini kiritishimiz kerak.

example.cpp
#include <unordered_map>

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

example.cpp
unordered_map<key_type, value_type> ump;

Bu yerga,

-key_type kalit uchun ma'lumotlar turini bildiradi -value_type qiymat uchun ma'lumotlar turini ko'rsatadi

Masalan,

example.cpp
// butun son kaliti va qiymati bilan unordered_map yarating
unordered_map<int, int> ump_integer;

// string kaliti va int qiymati bilan unordered_map yarating
unordered_map<string, int> ump_string;

Tartibsiz xaritani ishga tushiring

Biz C++ tartibsiz xaritasini quyidagi usullar bilan ishga tushirishimiz mumkin:

example.cpp
// Initializer ro' ext
unordered_map<string, int> unordered_map1 = {
  {"One", 1},
  {"Two", 2},
  {"Three", 3}
};

// Yagona ishga tushirish
unordered_map<string, int> unordered_map2 {
  {"One", 1},
  {"Two", 2},
  {"Three", 3}
};

Bu erda biz tartibsiz xaritani ularga bevosita qiymatlar berish orqali ishga tushirdik.

Endi unordered_map1 va unordered_map2 ham {{"One", 1}, {"Two", 2}, {"Three", 3}} bilan ishga tushirildi.

Misol: C++ unordered_map

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

int main() {

  // yagona ishga tushirish
  unordered_map<string, int> unordered_map1  {
  {"One", 1},
  {"Two", 2},
  {"Three", 3}
 };

  cout << "Key - Value" << endl;

  // tartibsiz xarita bo'ylab aylanish
  // kalit-qiymat juftlarini ko'rsatish
  for(const auto& key_value: unordered_map1) {
    string key = key_value.first;
    int value = key_value.second;
    
    cout << key << " - " << value << endl;
  }
  
  return 0;
}

Chiqish

kod
Key - Value
Three - 3
Two - 2
One - 1

Yuqoridagi misolda biz unordered_map1 nomli tartibsiz xaritani bir xil ishga tushirish yordamida e'lon qildik va ishga tushirdik.

example.cpp
unordered_map<string, int> unordered_map1 {
  {"One", 1},
  {"Two", 2},
  {"Three", 3}
};

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

example.cpp
for(const auto& key_value: unordered_map1) {
  string key = key_value.first;
  int value = key_value.second;    
  cout << key << " - " << value << endl;
}

Yuqoridagi kodda tartibsiz xaritaning har bir elementi (kalit-qiymat juftligi) key_value oʻzgaruvchisida saqlanadi.

Keyin biz kalit va qiymatni olamiz:

-key_value.first - kalitni beradi -key_value.second - qiymatni beradi

E'tibor bering, biz tartibsiz xaritani kalitlar tartibida yaratdik: "One" , "Two" , "Three" . Biroq, chiqish aniqlanmagan tartibda.

Buning sababi shundaki, elementlar kalit yoki qiymatlar asosida biron bir tartibda saqlanmaydi.

[!NOTE] Starting from C++17, you can use structure bindings to simplify this code further: for(const auto& [key, value]: unordered_map1) { cout << key << " - " << value << endl; }

C++ tartibsiz xaritasini ishga tushirishning boshqa usullari Biz diapazon usulini ishga tushirish yordamida bir tartibsiz xaritani boshqasiga nusxalashimiz mumkin. unordered_map<string, int> unordered_map_1 { {"One", 1}, {"Two", 2}, {"Three", 3} }; unordered_map<string, int> unordered_map_2(unordered_map_1.begin(), unordered_map_1.end()); Bu yerda biz birinchi navbatda unordered_map_1 nomli tartibsiz xaritani yaratdik. Keyin, unordered_map_1 ning barcha elementlarini nusxalash orqali unordered_map_2 deb nomlangan yana bir tartibsiz xarita yaratdik.

C++ tartibsiz xarita usullari

C++ tilida unordered_map klassi tartibsiz xaritada turli operatsiyalarni bajarish uchun turli usullarni taqdim etadi.

Usullar tavsifi insert() bir yoki bir nechta kalit-qiymat juftligini kiriting count() agar kalit mavjud bo'lsa 1ni, agar bo'lmasa 0ni qaytaradi find() iteratorni ko'rsatilgan kalit bilan elementga qaytaradi at() belgilangan kalitdagi elementni qaytaradi size() elementlar sonini qaytaradi empty() ko'rsatilgan elementlar sonini qaytaradi empty() agar tartibsiz elementni olib tashlashCODEX bilan tartiblanmagan bo'lsa clear() barcha elementlarni olib tashlaydi

Tartibsiz xaritaga kalit-qiymat juftlarini kiriting

Tartibsiz xaritaga kalit-qiymat juftligini quyidagi yordamida kiritishimiz mumkin:

  • insert() - insert key-value pairs
  • [] - insert a key and value

Masalan,

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

int main() {

  unordered_map<string, int> unordered_map1;
  
  // kalit-qiymat juftligini kiriting {"Bir", 1}
  unordered_map1["One"] = 1;

  // juftlik kiriting {"Ikki", 2}
  unordered_map1.insert({"Two", 2});

  // 
  unordered_map1.insert({{"Three", 3}, {"Four", 4}});
  
  cout << "Key - Value" << endl;

  // unordered_map1 elementlarini ko'rsatish
  for(const auto& key_value: unordered_map1) {
    string key = key_value.first;
    int value = key_value.second;
    
    cout << key << " - " << value << endl;
  }
 
  return 0;
}

Chiqish

kod
Key - Value
Four - 4
Two - 2
Three - 3
One - 1

Yuqoridagi misolda biz satr va butun sonning kalit-qiymat juftlarini saqlash uchun bo'sh tartibsiz xaritani ishga tushirdik.

Keyin [] yordamida {"One", 1} juftligini kiritdik.

example.cpp
unordered_map1["One"] = 1;

Keyin insert() usuli yordamida boshqa juftlikni kiritdik.

example.cpp
unordered_map1.insert({"Two", 2});

Nihoyat, insert() yordamida ikkita juftlik kiritdik.

example.cpp
unordered_map1.insert({{"Three", 3}, {"Four", 4}});

Tartibsiz xaritalarning qiymatlariga kirish

Tartibsiz xaritaning belgilangan kalitining qiymatlariga kirish uchun quyidagi usullardan foydalanishimiz mumkin:

-at() - belgilangan kalit uchun qiymatni qaytaradi -[] - belgilangan kalit uchun qiymatni qaytaradi

Masalan,

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

int main() {

  unordered_map<string, string> capital_city {
    {"Nepal", "Kathmandu"},
    {"India", "New Delhi"},
    {"Australia", "Canberra"}
  };
  
  cout << "Capital of Nepal is " << capital_city["Nepal"] << endl;
  cout << "Capital of Australia is " << capital_city.at("Australia");
  
  return 0;
}

Chiqish

kod
Capital of Nepal is Kathmandu
Capital of Australia is Canberra

Yuqoridagi misolda,

-capital_city["Nepal"] - elementni "Nepal" kaliti bilan qaytaradi -capital_city.at("Australia") - elementni "Australia" kaliti bilan qaytaradi

[!NOTE] Elementlarga kirish uchun [] operatoridan foydalanishimiz mumkin bo'lsa-da, at() usulidan foydalanish afzalroqdir. Buning sababi shundaki, at() belgilangan kalit mavjud bo'lmaganda istisno qiladi, [] esa kalitni axlat qiymati bilan bog'laydi. Masalan, // "Yaponiya" kaliti mavjud emas // shuning uchun "Yaponiya" kaliti axlat qiymati cout bilan bog'langan << "Yaponiya poytaxti: " << capital_city["Yaponiya"];

Tartibsiz xaritaning qiymatlarini o'zgartirish

Tartibsiz xarita qiymatini o'zgartirish uchun at() usuli yoki [] operatoridan foydalanishimiz mumkin. Masalan,

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

int main() {

  unordered_map<string, string> capital_city {
    {"India", "Calcutta"},
    {"Pakistan", "Karachi"},
  };
  
  cout << "Old Capitals:" << endl;
  cout << "India : " << capital_city["India"] << endl;
  cout << "Pakistan : " << capital_city["Pakistan"];
 
  // [] yordamida "Hindiston" qiymatini o'zgartirish
  capital_city["India"] = "New Delhi";

  // at() yordamida "Pokiston" qiymatini o'zgartirish
  capital_city.at("Pakistan") = "Islamabad";
  
  cout << "\n\nNew Capitals:" << endl;
  cout << "India : " << capital_city["India"] << endl;
  cout << "Pakistan : " << capital_city["Pakistan"];
  
  return 0;
}

Chiqish

kod
Old Capitals: 
India : Calcutta
Pakistan : Karachi

New Capitals: 
India : New Delhi
Pakistan : Islamabad

Yuqoridagi misolda, capital_city uchun dastlabki kalit-qiymat juftliklari {"India", "Calcutta"} va {"Pakistan", "Karachi"} hisoblanadi.

Keyin, biz [] operatoridan foydalanib, "India" kalitining qiymatini o'zgartirdik:

example.cpp
capital_city["India"] = "New Delhi";

Xuddi shunday, biz "Pakistan" kalitining qiymatini o'zgartirish uchun at() usulidan foydalanganmiz:

example.cpp
capital_city.at("Pakistan") = "Islamabad";

Tartibsiz xaritadan elementlarni olib tashlang

erase() usuli yordamida tartibsiz xaritaning belgilangan kaliti bilan elementni olib tashlashimiz mumkin. Masalan,

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

// display_unordered_map() funksiyasi prototipi
void display_unordered_map(const unordered_map<int, string> &);

int main() {

  unordered_map<int, string> student {
    {111, "John"},
    {132, "Mark"},
    {143, "Chris"}
  };
  
  cout << "Initial Unordered Map:\n";
  display_unordered_map(student);

  // Elementni kalit bilan olib tashlang: 143
  student.erase(143);
  
  cout << "\nFinal Unordered Map: \n";
  display_unordered_map(student);

  return 0;
}

// unordered_map elementlarini chop etish uchun yordamchi dastur
void display_unordered_map(const unordered_map<int, string> &umap){

  for(const auto& key_value: umap) {
    int key = key_value.first;
    string value = key_value.second;
    
    cout << key << " - " << value << endl;
  }
}

Chiqish

kod
Initial Unordered Map:
143 - Chris
132 - Mark
111 - John

Final Unordered Map: 
132 - Mark
111 - John

Yuqoridagi misolda biz tartibsiz xaritadan elementni olib tashlash uchun erase() usulidan foydalanganmiz.

Dastlab talaba nomli tartibsiz xaritaning mazmuni {{"143": Chris}, {"132": Mark}, {"111": John}} dir.

Keyin biz 143 kaliti bilan elementni olib tashlash uchun erase() usulidan foydalandik.

example.cpp
// elementni 143 kaliti bilan olib tashlaydi
student.erase(143);

Shunday qilib, yakuniy tarkib {{"132": Mark}, {"111": John}} bo'ladi.

[!NOTE] Tartibsiz xaritaning barcha elementlarini olib tashlash uchun clear() usulidan foydalanishimiz mumkin.

Tartibsiz xaritada kalit mavjudligini tekshiring

Belgilangan kalit tartibsiz xaritada mavjudligini tekshirish uchun quyidagi usullardan foydalanishimiz mumkin.

-find() - kalit topilsa, iteratorni elementga qaytaradi, aks holda end() iteratorini qaytaradi. -count() - agar kalit mavjud bo'lsa 1 ni, agar mavjud bo'lmasa 0 ni qaytaradi

Masalan,

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

int main() {

  unordered_map<int, string> student{
      {111, "John"},
      {132, "Mark"},
      {143, "Chris"}
  };

  cout << "Using find():" << endl;
  cout << "Does id " << 143 << " exist? ";

  // find() kalit topilmasa student.end() ni qaytaradi
  if (student.find(143) != student.end()) {
    cout << "Yes";
  }
  else {
    cout << "No";
  }

  cout << "\n\nUsing count():" << endl;
  cout << "Does id " << 1433 << " exist? ";

  // Agar kalit mavjud bo'lmasa, count() 0 ni qaytaradi
  if (student.count(1433)) {
    cout << "Yes";
  }
  else {
    cout << "No";
  }

  return 0;
}

Chiqish

kod
Using find():
Does id 143 exist? Yes

Using count():
Does id 1433 exist? No

Yuqoridagi misolda biz find() va count() dan tartibsiz xaritada berilgan kalit mavjudligini tekshirish uchun foydalandik.

Dastlab biz 143 kaliti mavjudligini tekshirish uchun find() usulidan foydalandik.

example.cpp
// 143-kalit mavjudligini tekshiradi
if (student.find(143) != student.end()) {
  cout << "Yes";
}
else {
  cout << "No";
}

find() usuli, agar mavjud bo'lsa, elementga ishora qiluvchi iteratorni qaytaradi. Agar kalit mavjud bo'lmasa, u end() iteratoriga ishora qiladi.

Keyin biz 1433 kaliti mavjudligini tekshirish uchun count() usulidan foydalandik.

example.cpp
// 1433 kaliti mavjudligini tekshiradi
if (student.count(1433)) {
  cout << "Yes";
}
else {
  cout << "No";
}