Programming Basics SQL HTML CSS JavaScript React Python C++ Java JavaFX Swing Problem Solving English English Conversations Computer Fundamentals Linux Learn Typing

C++الكلاس unordered_multimap

  • تعريف الكلاس unordered_multimap
  • دوال الكلاس unordered_multimap
  • أمثلة شاملة حول التعامل مع الكلاس unordered_unordered_multimap

تعريف الكلاس unordered_multimap

تم إضافة هذا الكلاس إبتداءاً من الإصدر c++11 و هو يستخدم لإنشاء كائن يمثل حاوية تخزن العناصر التي نضيفها فيها بشكل جدول يتألف من عمودين حيث يتكون كل عنصر من مفتاح ( Key ) يوضع في العمود الأول و قيمة ( Value ) توضع في العمود الثاني بالإضافة إلى أنها ترتب العناصر بالإعتماد على دالة مخصصة لذلك إسمها Hash() تقوم بالتشييك على مفتاح أي عنصر سيتم إدخاله لتحديد المكان الذي يجب وضعه فيها مع الإشارة إلى أنه يمكن وضع نفس المفتاح لأكثر من عنصر.

بالمبدأ الدالة Hash() تقوم بإجراء عملية حسابية على مفتاح أي عنصر يتم إدخاله.
أي ناتج ترجعه الدالة Hash() يتم تخزينه في الذاكرة في مكان خاص يقال له Bucket.
أي عنصر جديد يتم إضافته تقوم الدالة Hash() بإجراء العملية الحسابية عليه و مقارنة الناتج النهائي مع قيمة كل Buckets نتجت سابقاً و في حال تطابق الناتج مع قيمة أي Bucket سيتم وضعه في آخرها, أما في حال عدم تطابق الناتج مع قيمة أي Bucket سيتم إضافة Bucket جديد و وضعه فيها كالتالي.



القيمة المفتاحية لكل عنصر يمكن أن تكون من أي نوع تريده, و لكن في أغلب الأوقات ستكون المفاتيح عبارة عن أعداد أو كلمات.


معلومة تقنية

الفرق الوحيد بين الحاوية التي تنشئها من الكلاس unordered_map و الحاوية التي تنشئها من الكلاس unordered_multimap هو أن هذا الأخير يمكنه أن يستخدم نفس المفتاح لأكثر من عنصر.
الآن, بما أن مفاتيح العناصر في هذه الحاوية يمكن أن تكون مكررة فهذا يعني أنه لا يمكنك الإعتماد على قيم المفاتيح للتفرقة بين العناصر حيث أن المفتاح الواحد يمكن أن يرمز لعدة عناصر.


لاستخدام الكلاس unordered_multimap - أي حتى تتمكن من إنشاء كائنات منه - يجب تضمين الملف #include<unordered_multimap> لأنه موجود فيه.


بناء الكلاس

template < class Key,                                    // unordered_multimap::key_type
           class T,                                      // unordered_multimap::mapped_type
           class Hash = hash<Key>,                       // unordered_multimap::hasher
           class Pred = equal_to<Key>,                   // unordered_multimap::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_multimap::allocator_type
           > class unordered_multimap;

إذاً عند إنشاء كائن من الكلاس unordered_multimap يجب أن نمرر له نوع المفاتيح التي نريد تخزينها فيه مكان الباراميتر Key و نوع القيم التي نريد تخزينها فيه مكان الباراميتر T.

دوال الكلاس unordered_multimap

الجدول التالي يحتوي على دوال الكلاس unordered_multimap التي تستخدم للحصول على عداد يتيح المرور على عناصره.

الدالة مع تعريفها
1 iterator begin() ترجع كائن iterator يشير لمكان أول عنصر في الكائن الذي قام باستدعائها.
إذا كنا ننوي استخدام الدالة begin() بداخل حلقة فإننا نستخدم معها الدالة end() من أجل البدء من أول عنصر و الوقوف عند آخر عنصر.
2 iterator end() ترجع كائن iterator يشير لمكان آخر عنصر في الكائن الذي قام باستدعائها.
إذا كنا ننوي استخدام الدالة begin() بداخل حلقة فإننا نستخدم معها الدالة end() من أجل البدء من أول عنصر و الوقوف عند آخر عنصر.
3 local_iterator begin(size_t n) ترجع كائن iterator يشير لمكان أول عنصر بداخل Bucket محدد في الكائن الذي قام باستدعائها.
مكان الباراميتر n نمرر رقم الـ Bucket الذي نريد البدأ من أول عنصر موجود فيه.
4 local_iterator end(size_t n) ترجع كائن iterator يشير لمكان آخر عنصر بداخل Bucket محدد في الكائن الذي قام باستدعائها.
مكان الباراميتر n نمرر رقم الـ Bucket الذي نريد الوقوف عند آخر عنصر موجود فيه.

الجدول التالي يحتوي على دوال الكلاس unordered_multimap التي تستخدم للحصول على عدد عناصره.

الدالة مع تعريفها
1 bool empty() تستخدم لمعرفة ما إن كان الكائن الذي قام باستدعائها فارغاً أم لا.
ترجع false في حال كان يوجد فيه عنصر أو أكثر, و ترجع true إن لم يكن كذلك.
2 size_t size() تستخدم للحصول على عدد العناصر الموجودة في الكائن الذي قام باستدعائها.
3 size_t max_size() تستخدم للحصول على أكبر عدد عناصر يمكن تخزينها في الكائن الذي قام باستدعائها.

الجدول التالي يحتوي على دوال الكلاس unordered_multimap التي تستخدم للوصول لقيم عناصره.

الدالة مع تعريفها
1 unordered_multimapped_type& at(key_type& k) تستخدم للوصول لقيمة عنصر محدد في الكائن الذي قام باستدعائها سواء لتغييرها أو للحصول عليها.
مكان الباراميتر k نمرر لها مفتاح العنصر الذي نريد الوصول إليه.
ترمي الإستثناء out_of_range في حال كانت قيمة k لا تمثل القيمة المفتاحية لأي عنصر موجود في الكائن.

معلومة: يمكنك استخدام العامل [] للوصول للعنصر و لكن عليك معرفة أن استخدام هذا العامل لا يرمي إستثناء في حال تمرير قيمة مفتاح غير موجود في الكائن.
2 operator[] (key_type& k) يستخدم العامل [] للوصول لقيمة عنصر محدد في الكائن الذي قام باستدعائها سواء لتغييرها أو للحصول عليها.
مكان الباراميتر k نمرر لها مفتاح العنصر الذي نريد الوصول إليه.
في حال تمرير قيمة مفتاح غير موجود مكان الباراميتر k سيتم إضافة العنصر كعنصر جديد في الكائن.

الجدول التالي يحتوي على دوال الكلاس unordered_multimap التي تستخدم للتحكم بعناصره.

الدالة مع تعريفها
1 pair<K, V> insert({key, value}) تستخدم لإضافة عنصر جديد في الكائن الذي قام باستدعائها.
مكان الباراميتر key نمرر القيمة المفتاحية للعنصر الذي نريد إضافته.
مكان الباراميتر value نمرر القيمة التي نريد وضعها في العنصر الذي سيتم إضافته.
كما أنها ترجع نسخة من العنصر الذي تم إضافته.
2 pair<K, V> emplace(Args&&... args) تستخدم لإضافة عنصر جديد في الكائن الذي قام باستدعائها تماماً كالدالة insert().
مكان الباراميتر Args نمرر القيمة المفتاحية للعنصر الذي نريد إضافته ثم نضع فاصلة و نمرر القيمة التي نريد وضعها فيه.
كما أنها ترجع نسخة من العنصر الذي تم إضافته.
3 size_t erase(key_type& k) تستخدم لحذف عنصر محدد من الكائن الذي قام باستدعائها من خلال المفتاح الخاص به.
مكان الباراميتر k نمرر مفتاح العنصر الذي نريد حذفه.
4 iterator erase(const_iterator position) تستخدم لحذف عنصر محدد من الكائن الذي قام باستدعائها من خلال الإشارة إلى مكانه فيه.
مكان الباراميتر position نمرر كائن أصله من Iterator يشير لعنوان العنصر الذي سيتم حذفه.
5 iterator erase(const_iterator first, const_iterator last) تستخدم لحذف مجموعة عناصر من الكائن الذي قام باستدعائها من خلال الإشارة إلى مكان وجود هذه العناصر.
مكان الباراميتر first نمرر كائن أصله من const_iterator يشير لعنوان العنصر الذي سيتم بدء الحذف من عنده.
مكان الباراميتر last نمرر كائن أصله من const_iterator يشير لعنوان العنصر الذي سيتم إيقاف الحذف عنده.
6 void swap(unordered_multimap& anotherMap) تستخدم لتبديل قيم عناصر الكائن الذي قام باستدعائها بقيم عناصر الكائن الذي نمرره لها.
مكان الباراميتر anotherMap نمرر لها كائن من الكلاس unordered_multimap يملك نفس نوع عناصر الكائن الذي قام باستدعائها.

الجدول التالي يحتوي على دوال الكلاس unordered_multimap التي تستخدم للبحث فيه.

الدالة مع تعريفها
1 size_t count(const key_type& k) تستخدم لمعرفة عدد العناصر التي تملك مفتاح محدد في الكائن الذي قام باستدعائها.
مكان الباراميتر k نمرر المفتاح الذي نريد معرفة عدد العناصر التي تملكه.
2 iterator find(const T& k) تستخدم للبحث في الكائن الذي قام باستدعائها عن مكان أول عنصر يملك مفتاح محدد.
مكان الباراميتر k نمرر المفتاح الذي نريد البحث عن أول عنصر يملكه.
في حال تم إيجاد عنصر يملك نفس المفتاح الذي تم تمريره لها ترجع كائن من Iterator يشير لعنوان العنصر في الذاكرة.
و في حال لم يتم إيجاد عنصر يملك نفس المفتاح الذي تم تمريره لها ترجع كائن من Iterator قيمته تساوي القيمة التي ترجعها الدالة end().

أمثلة شاملة حول التعامل مع الكلاس unordered_unordered_multimap

في كل مثال موضوع قمنا باستخدام دوال جديدة حتى تعرف كيف تستخدم جميع الدوال التي ذكرناها في الجدول.


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها string قيم و نوعها string أيضاً.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن إسم البلد كمفتاح و إسم مدينة موجودة فيه كقيمة.
بعدها قمنا بطباعة عدد العناصر التي قمنا بإضافتها.
في الأخير قمنا بعرض جميع مفاتيح و قيم العناصر الموجودة فيه بواسطة حلقة.

ملاحظة: قمنا باستخدام الدالة emplace() لإضافة العناصر, الدالة size() لمعرفة عدد العناصر التي تم إضافتها. عند عرض جميع قيم عناصر الكائن, قمنا باستخدام الدالة begin() للحصول على مؤشر للعنصر الأول لأننا سنبدأ من عنده و الدالة end() للحصول على مؤشر للعنصر الأخير لأننا سنتوقف عنده.

المثال الأول

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها string يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<string, string> um;

    // كل عنصر يحتوي على إسم البلد كمفتاح و إحدى مدنه كقيمة ,um هنا قمنا بإضافة 12 عنصر في الكائن
    um.emplace("Egypt", "Giza");
    um.emplace("Lebanon", "Beirut");
    um.emplace("Syria", "Sweida");
    um.emplace("Lebanon", "Tripolie");
    um.emplace("Syria", "Idlib");
    um.emplace("KSA", "Riyadh");
    um.emplace("Egypt", "Cairo");
    um.emplace("Lebanon", "Sidon");
    um.emplace("Syria", "Damascus");
    um.emplace("KSA", "Makkah");
    um.emplace("Syria", "Homs");
    um.emplace("Algeria", "Algiers");
    
    // size() باستخدام الدالة um هنا قمنا بطباعة عدد عناصر الكائن
    cout << "um size = " << um.size() << "\n\n";
    
    cout << "um keys and values\n";
    cout << "---------------------\n";

    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه um هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = um.begin(); it != um.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << "\t | " << it->second << "\n";
    }

    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

um size = 12

um keys and values
---------------------
Algeria  | Algiers
Lebanon  | Sidon
Lebanon  | Tripolie
Lebanon  | Beirut
KSA      | Makkah
KSA      | Riyadh
Egypt    | Cairo
Egypt    | Giza
Syria    | Homs
Syria    | Damascus
Syria    | Idlib
Syria    | Sweida


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها int قيم و نوعها string.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن عدد و كمفتاح و إسمه باللغة الإنجليزية أو الفرنسية كقيمة.
بعدها قمنا بعرض القيم الموجودة فيه بواسطة حلقة.

المثال الثاني

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها int يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<int, string> um = {
        {1, "One"},
        {2, "Two"},
        {3, "Three"},
        {4, "Four"},
        {5, "Five"},
    };
    
    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه um هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = um.begin(); it != um.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << " - " << it->second << "\n";
    }

    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

5 - Five
4 - Four
3 - Three
2 - Two
1 - One


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها string قيم و نوعها string أيضاً.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن إسم البلد كمفتاح و إسم مدينة موجودة فيه كقيمة.
في الأخير قمنا بالبحث عن عدد العناصر التي تملك مفتاح محدد و طباعة نتيجة البحث.

ملاحظة: قمنا باستخدام الدالة count() لمعرفة عدد العناصر التي تملك مفتاح محدد في الكائن.

المثال الثالث

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها string يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<string, string> um;

    // كل عنصر يحتوي على إسم البلد كمفتاح و إحدى مدنه كقيمة ,um هنا قمنا بإضافة 12 عنصر في الكائن
    um.emplace("Egypt", "Giza");
    um.emplace("Lebanon", "Beirut");
    um.emplace("Syria", "Sweida");
    um.emplace("Lebanon", "Tripolie");
    um.emplace("Syria", "Idlib");
    um.emplace("KSA", "Riyadh");
    um.emplace("Egypt", "Cairo");
    um.emplace("Lebanon", "Sidon");
    um.emplace("Syria", "Damascus");
    um.emplace("KSA", "Makkah");
    um.emplace("Syria", "Homs");
    um.emplace("Algeria", "Algiers");
    
    // um في الكائن "Syria" هنا قمنا بطباعة عدد العناصر التي تملك قيمة تساوي
    cout << "Total number of elements with key 'Syria' = " << um.count("Syria");
    
    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

Total number of elements with key 'Syria' = 4


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها string قيم و نوعها string أيضاً.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن إسم البلد كمفتاح و إسم مدينة موجودة فيه كقيمة.
بعدها قمنا بحذف جميع العناصر التي تملك مفاتيح محددة منه و من ثم طباعة قيم جميع العناصر المتبقية بواسطة حلقة.

ملاحظة: قمنا باستخدام الدالة erase() لحذف جميع العناصر التي تملك مفاتيح محددة.

المثال الرابع

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها string يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<string, string> um;

    // كل عنصر يحتوي على إسم البلد كمفتاح و إحدى مدنه كقيمة ,um هنا قمنا بإضافة 12 عنصر في الكائن
    um.emplace("Egypt", "Giza");
    um.emplace("Lebanon", "Beirut");
    um.emplace("Syria", "Sweida");
    um.emplace("Lebanon", "Tripolie");
    um.emplace("Syria", "Idlib");
    um.emplace("KSA", "Riyadh");
    um.emplace("Egypt", "Cairo");
    um.emplace("Lebanon", "Sidon");
    um.emplace("Syria", "Damascus");
    um.emplace("KSA", "Makkah");
    um.emplace("Syria", "Homs");
    um.emplace("Algeria", "Algiers");
    
    // um من الكائن "Syria" و المتفاح "Lebanon" هنا قمنا بحذف جميع العناصر التي تملك المفتاح
    um.erase("Lebanon");
    um.erase("Syria");

    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه um هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = um.begin(); it != um.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << " -> " << it->second << "\n";
    }
    
    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

Algeria -> Algiers
KSA -> Makkah
KSA -> Riyadh
Egypt -> Cairo
Egypt -> Giza


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها int قيم و نوعها string.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن عدد و كمفتاح و إسمه باللغة الإنجليزية أو الفرنسية كقيمة.
بعدها قمنا بالبحث عن أول عنصر يملك مفتاح محدد فيه و من ثم قمنا بحذفه.
في الأخير قمنا بطباعة قيم جميع العناصر المتبقية بواسطة حلقة.

ملاحظة: قمنا باستخدام الدالة find() للبحث عن أول عنصر يملك مفتاح محدد في الكائن و الدالة erase() لحذف العنصر منه.

المثال الخامس

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها int يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<int, string> um = {
        {1, "Un"},
        {1, "One"},
        {2, "Deux"},
        {2, "Two"},
        {3, "Trois"},
        {3, "Three"}
    };

    // نجده يملك المفتاح الذي سنبحث عنه um لتخزين مكان أول عنصر في الكائن unordered_multimap<int, string>::iterator منا قمنا بتعريف كائن من 
    unordered_multimap<int, string>::iterator it;

    // it عن أول عنصر يملك مفتاح يساوي 2, و بالتالي في حال وجود عنصر يملك هذا المفتاح سيتم تخزين عنوانه في الكائن um هنا قمنا بالبحث في الكائن
    // فيه للإشارة إلى أنه لم يتم إيجاد أي عنصر يملك هذا المفتاح um.end() في حال عدم وجود عنصر يملك مفتاح يساوي 2 سيتم تخزين القيمة التي ترجعها
    it = um.find(2);

    // فهذا يعني أنه تم إيجاد العنصر و بالتالي سيتم تنفيذ الكود الموضوع بالداخل um.end() لا تساوي القيمة التي ترجعها الدالة it في حال كانت قيمة
    if (it != um.end())
    {
        // و من ثم قمنا بحذفه um هنا قمنا بطباعة مفتاح و قيمة العنصر الذي تم إيجاده في الكائن
        cout << "Element with key '"<< it->first << "' and value '" << it->second << "' is removed from um\n\n";
        um.erase(it);
    }

    cout << "um keys and values:\n";

    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه um هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = um.begin(); it != um.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << " - " << it->second << "\n";
    }
    
    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

Element with key '2' and value 'Two' is removed from um

um keys and values:
3 - Three
3 - Trois
2 - Deux
1 - One
1 - Un


في المثال التالي قمنا بتعريف كائنين من unordered_multimap مع تحديد أن عناصرهما تتكون من مفاتيح نوعها int قيم و نوعها string مع إضافة عدة عناصر فيهما عند تعريفهم.
بعدها قمنا بتبديل عناصرهما و من ثم طباعة مفاتيح و قيم عناصرهما بواسطة حلقة للتأكد من أن التبديل قد تم بنجاح.

ملاحظة: قمنا باستخدام الدالة swap() لتبديل عناصرهما.

المثال السادس

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // بالإضافة إلى أننا قمنا بإضافة عدة قيم فيه string و قيم نوعها int يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<int, string> unordered_multimap1 = {
        {1, "One"},
        {2, "Two"},
        {3, "Three"},
        {4, "Four"}
    };
    
    // بالإضافة إلى أننا قمنا بإضافة عدة قيم فيه string و قيم نوعها int يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن آخر من الكلاس
    unordered_multimap<int, string> unordered_multimap2 = {
        {5, "Five"},
        {6, "Six"},
        {7, "Seven"},
        {8, "Eight"}
    };

    // unordered_multimap2 مع قيم الكائن unordered_multimap1 هنا قمنا بتبديل قيم الكائن
    unordered_multimap1.swap(unordered_multimap2);
    
    cout << "unordered_multimap1 keys and values:\n";

    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه unordered_multimap1 هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = unordered_multimap1.begin(); it != unordered_multimap1.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << " - " << it->second << "\n";
    }
    
    cout << "\nunordered_multimap2 keys and values:\n";

    // إبتداءاً من أول عنصر وصولاً لآخر عنصر فيه unordered_multimap2 هنا قمنا بإنشاء حلقة تقوم في كل دورة بطباعة قيم عنصر جديد من العناصر الموجودة في الكائن
    for (auto it = unordered_multimap2.begin(); it != unordered_multimap2.end(); ++it)
    {
        // تمثل قيمة العمود الأول في العنصر و التي تعتبر المفتاح الخاص به first الخاصية
        // تمثل قيمة العمود الثاني في العنصر و التي تمثل قيمته second و الخاصية
        cout << it->first << " - " << it->second << "\n";
    }

    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

unordered_multimap1 keys and values:
8 - Eight
7 - Seven
6 - Six
5 - Five

unordered_multimap2 keys and values:
4 - Four
3 - Three
2 - Two
1 - One


في المثال التالي قمنا بتعريف كائن من unordered_multimap مع تحديد أن عناصره تتكون من مفاتيح نوعها string قيم و نوعها string أيضاً.
بعدها قمنا بإضافة بعض العناصر فيه, كل عنصر عبارة منهم عبارة عن إسم البلد كمفتاح و إسم مدينة موجودة فيه كقيمة.
في الأخير قمنا بعرض مفاتيح و قيم العناصر الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.

ملاحظة: قمنا باستخدام الدالة bucket_count() لمعرفة كم Bucket تم إنشاؤها بشكل تلقائي و الدالة bucket_size() لمعرفة عدد العناصر الموجودة في كل Bucket.

المثال السابع

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // string و قيم نوعها string يمكنه أن يحتوي على مفاتيح نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    unordered_multimap<string, string> um;

    // كل عنصر يحتوي على إسم البلد كمفتاح و إحدى مدنه كقيمة ,um هنا قمنا بإضافة 12 عنصر في الكائن
    um.emplace("Egypt", "Giza");
    um.emplace("Lebanon", "Beirut");
    um.emplace("Syria", "Sweida");
    um.emplace("Lebanon", "Tripolie");
    um.emplace("Syria", "Idlib");
    um.emplace("KSA", "Riyadh");
    um.emplace("Egypt", "Cairo");
    um.emplace("Lebanon", "Sidon");
    um.emplace("Syria", "Damascus");
    um.emplace("KSA", "Makkah");
    um.emplace("Syria", "Homs");
    um.emplace("Algeria", "Algiers");

    // totalBuckets التي تم إنشاؤها في المتغير Buckets هنا قمنا بتخزين عدد جميع الـ
    int totalBuckets = um.bucket_count();

    // um الموجودين في الكائن Buckets هنا قمنا بإنشاء حلقة تمر على جميع الـ
    for(int i=0; i<totalBuckets; i++)
    {
        // Bucket في كل دورة سيتم طباعة رقم الـ
        cout << "bucket[" << i << "] elements:";

        // و من ثم طباعة مفتاح و قيمة كل عصنر موجود فيها الحلقة التالية
        for(auto it=um.begin(i); it!=um.end(i); ++it)
        {
            cout << " [" << it->first << " : " << it->second << "]";
        }

        cout << endl;
    }
}

سنحصل على النتيجة التالية عند التشغيل.

bucket[0] elements: [KSA : Makkah] [KSA : Riyadh]
bucket[1] elements:
bucket[2] elements:
bucket[3] elements: [Syria : Homs] [Syria : Damascus] [Syria : Idlib] [Syria : Sweida]
bucket[4] elements:
bucket[5] elements:
bucket[6] elements:
bucket[7] elements: [Lebanon : Sidon] [Lebanon : Tripolie] [Lebanon : Beirut]
bucket[8] elements:
bucket[9] elements:
bucket[10] elements:
bucket[11] elements: [Egypt : Cairo] [Egypt : Giza]
bucket[12] elements:
bucket[13] elements:
bucket[14] elements:
bucket[15] elements: [Algeria : Algiers]
bucket[16] elements:


في المثال التالي قمنا بتعريف كائن من unordered_multimap مخصص لتخزين عناصر تتكون من مفاتيح نوعها string و قيم نوعها string أيضاً مع إضافة عدة عناصر فيه عند تعريفه.
بعدها قمنا بعرض عدد العناصر الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.

ملاحظة: قمنا باستخدام الدالة bucket_count() لمعرفة كم Bucket تم إنشاؤها بشكل تلقائي.

المثال الثامن

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    // بالإضافة إلى أننا قمنا بإضافة عدة قيم فيه string يمكنه أن يحتوي على عناصر نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    // كل عنصر يحتوي على إسم البلد كمفتاح و إحدى مدنه كقيمة ,um هنا قمنا بإضافة 12 عنصر في الكائن
    unordered_multimap<string, string> um = {
        {"Egypt", "Giza"},
        {"Lebanon", "Beirut"},
        {"Syria", "Sweida"},
        {"Lebanon", "Tripolie"},
        {"Syria", "Idlib"},
        {"KSA", "Riyadh"},
        {"Egypt", "Cairo"},
        {"Lebanon", "Sidon"},
        {"Syria", "Damascus"},
        {"KSA", "Makkah"},
        {"Syria", "Homs"},
        {"Algeria", "Algiers"}
    };

    // totalBuckets التي تم إنشاؤها في المتغير Buckets هنا قمنا بتخزين عدد جميع الـ
    int totalBuckets = um.bucket_count();

    // um الموجودين في الكائن Buckets هنا قمنا بإنشاء حلقة تمر على جميع الـ
    for(int i=0; i<totalBuckets; i++)
    {
        // و عدد العناصر الموجودة فيها Bucket في كل دورة سيتم طباعة رقم الـ
        cout << "bucket[" << i << "] total elements = " << um.bucket_size(i);

        cout << endl;
    }
}

سنحصل على النتيجة التالية عند التشغيل.

bucket[0] total elements = 0
bucket[1] total elements = 0
bucket[2] total elements = 3
bucket[3] total elements = 0
bucket[4] total elements = 0
bucket[5] total elements = 6
bucket[6] total elements = 1
bucket[7] total elements = 0
bucket[8] total elements = 0
bucket[9] total elements = 0
bucket[10] total elements = 2
bucket[11] total elements = 0
bucket[12] total elements = 0


في المثال التالي قمنا بتعريف كائن من unordered_multimap مخصص لتخزين مفاتيح نوعها string و قيم نوعها string أيضاً مع تحديد الطريقة التي سيتم على أساسها توزيع العناصر في Buckets و إضافة عدة عناصر فيه عند تعريفه.
لتحديد الطريقة التي سيتم على أساسها توزيع العناصر في Buckets قمنا بإنشاء كلاس إسمه Hash و إعادة تعريف العامل () حتى يقارن مفتاح أي عنصر نريد إضافته نسبةً لعدد الأحرف الموجودة فيه, عندها يتم وضع العناصر التي تملك مفتاح يتألف من حرف واحد في Bucket, و العناصر التي تملك مفتاح يتألف من حرفين في Bucket, و العناصر التي تملك مفتاح يتألف من ثلاثة أحرف في Bucket و هكذا..
في النهاية قمنا بعرض مفاتيح و قيم العناصر الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.

المثال التاسع

main.cpp
#include <iostream>
#include <unordered_map>

using namespace std;

// unordered_multimap سنستخدمه لاحقاً لتحديد كيف ستترتب العناصر في الحاوية التي ننشئها من الكلاس Hash هنا قمنا بتعريف كلاس إسمه
class Hash
{
    public:
        // Bucket حتى يقرر في أي unordered_multimap هنا قمنا بتعريف العامل الذي سيستخدمه الكائن الذي ننشئه من الكلاس
        // key سيتم وضع العنصر الذي نضيفه فيه مع الإشارة إلى أن المفتاح الذي يملكه العنصر سيتم تمريره مكان الباراميتر
        size_t operator() (const string &key) const
        {
            // سيتم إضافة العنصر Bucket في النهاية سيتم إرجاع عدد أحرف مفتاح العنصر لأنها التي ستحدد في أي
            return key.length();
        }
};

int main()
{
    // مع تحديد أنه يعتمد string يمكنه أن يحتوي على عناصر مفاتيحها و قيمها نوعها unordered_multimap هنا قمنا بتعريف كائن من الكلاس
    // من أجل تحديد الطريقة التي سيتم فيها ترتيب العناصر التي نضيفها فيه, بالإضافة إلى أننا قمنا بإضافة عدة قيم فيه Hash على الكلاس
    unordered_multimap<string, string, Hash> um = {
        {"Egypt", "Giza"},
        {"Lebanon", "Beirut"},
        {"Syria", "Sweida"},
        {"Lebanon", "Tripolie"},
        {"Syria", "Idlib"},
        {"KSA", "Riyadh"},
        {"Egypt", "Cairo"},
        {"Lebanon", "Sidon"},
        {"Syria", "Damascus"},
        {"KSA", "Makkah"},
        {"Syria", "Homs"},
        {"Algeria", "Algiers"}
    };
    
    // totalBuckets التي تم إنشاؤها في المتغير Buckets هنا قمنا بتخزين عدد جميع الـ
    int totalBuckets = um.bucket_count();

    // um الموجودين في الكائن Buckets هنا قمنا بإنشاء حلقة تمر على جميع الـ
    for(int i=0; i<totalBuckets; i++)
    {
        // Bucket في كل دورة سيتم طباعة رقم الـ
        cout << "bucket[" << i << "] elements:";

        // و من ثم طباعة مفتاح و قيمة كل عصنر موجود فيها الحلقة التالية
        for(auto it=um.begin(i); it!=um.end(i); ++it)
        {
            cout << " [" << it->first << " : " << it->second << "]";
        }
        
        cout << endl;
    }

    return 0;
}

سنحصل على النتيجة التالية عند التشغيل, و لاحظ كيف تم ترتيب العناصر على أساس عدد الأحرف التي يتألف منها كل عنصر.

bucket[0] elements:
bucket[1] elements:
bucket[2] elements:
bucket[3] elements: [KSA : Makkah] [KSA : Riyadh]
bucket[4] elements:
bucket[5] elements: [Syria : Homs] [Syria : Damascus] [Syria : Idlib] [Syria : Sweida] [Egypt : Cairo] [Egypt : Giza]
bucket[6] elements:
bucket[7] elements: [Algeria : Algiers] [Lebanon : Sidon] [Lebanon : Tripolie] [Lebanon : Beirut]
bucket[8] elements:
bucket[9] elements:
bucket[10] elements:
bucket[11] elements:
bucket[12] elements: