C++الكلاس unordered_multiset
- تعريف الكلاس unordered_multiset
- دوال الكلاس unordered_multiset
- أمثلة شاملة حول التعامل مع الكلاس unordered_multiset
تعريف الكلاس unordered_multiset
تم إضافة هذا الكلاس إبتداءاً من الإصدر c++11
و هو يستخدم لإنشاء كائن يمثل حاوية تخزن العناصر التي نضيفها فيها بترتيب معين يتم تحديده من قبل دالة مخصصة لذلك إسمها Hash() تقوم بالتشييك على قيم أي عنصر سيتم إدخاله لتحديد المكان الذي يجب وضعه فيه مع الإشارة إلى أنه يمكن تخزين قيم مكررة فيها.
بالمبدأ الدالة Hash() تقوم بإجراء عملية حسابية على قيم أي عنصر يتم إدخاله.
أي ناتج جديد غير مكرر ترجعه الدالة Hash() يتم تخزينه في الذاكرة في مكان خاص يقال له Bucket.
أي عنصر جديد يتم إضافته تقوم الدالة Hash() بإجراء العملية الحسابية عليه و مقارنة الناتج النهائي مع قيمة كل Buckets نتجت سابقاً و في حال تطابق الناتج مع قيمة أي Bucket سيتم وضعه في آخرها, أما في حال عدم تطابق الناتج مع قيمة أي Bucket سيتم إضافة Bucket جديد و وضعه فيها كالتالي.
كما أنه بإمكانك تعريف الدالة طريقة عمل الدالة Hash() بنفسك حتى تحدد الطريقة التي سيتم على أساسها إنشاء Buckets و ترتيب العناصر ضمنهم.
على سبيل المثال إذا كنت تنوي إنشاء حاوية خاصة لتخزين الأعداد, يمكنك جعل الدالة Hash() تنشئ Buckets على حسب عدد الأرقام التي يتألف منها كل عدد. عندها سيتم ترتيب العناصر كالتالي:
- العدد الذي يتألف من رقم واحد مثل
3
-7
سيتم وضعهما في Bucket. - العدد الذي يتألف من رقمين واحد مثل
12
-45
سيتم وضعهما في Bucket. - العدد الذي يتألف من ثلاثة أرقام مثل
100
-273
سيتم وضعهما في Bucket و هكذا..
معلومة تقنية
الفرق الوحيد بين الحاوية التي تنشئها من الكلاس unordered_set و الحاوية التي تنشئها من الكلاس unordered_multiset هو أن هذا الأخير يمكنه أن يحتوي على أكثر من عنصر عندهم نفس القيمة.
الآن, بما أن مفاتيح العناصر في هذه الحاوية يمكن أن تكون مكررة فهذا يعني أنه لا يمكنك الإعتماد على قيم المفاتيح للتفرقة بين العناصر حيث أن المفتاح الواحد يمكن أن يرمز لعدة عناصر.
لاستخدام الكلاس unordered_multiset - أي حتى تتمكن من إنشاء كائنات منه - يجب تضمين الملف #include<unordered_set> لأنه موجود فيه.
بناء الكلاس
إذاً عند إنشاء كائن من الكلاس unordered_multiset يجب أن نمرر له نوع البيانات الذي نريد تخزينه فيه مكان الباراميتر Key
.
دوال الكلاس unordered_multiset
الجدول التالي يحتوي على دوال الكلاس unordered_multiset التي تستخدم للحصول على عداد يتيح المرور على عناصره.
الدالة مع تعريفها | |
---|---|
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_multiset التي تستخدم للحصول على عدد عناصره.
الدالة مع تعريفها | |
---|---|
1 | bool empty()
تستخدم لمعرفة ما إن كان الكائن الذي قام باستدعائها فارغاً أم لا. ترجع false في حال كان يوجد فيه عنصر أو أكثر, و ترجع true إن لم يكن كذلك. |
2 | size_t size() تستخدم للحصول على عدد العناصر الموجودة في الكائن الذي قام باستدعائها. |
3 | size_t max_size() تستخدم للحصول على أكبر عدد عناصر يمكن تخزينها في الكائن الذي قام باستدعائها. |
4 | size_t bucket_count() تستخدم للحصول على عدد الـ Buckets الموجودين في الكائن الذي قام باستدعائها. |
5 | size_t bucket_size(size_t n)
تستخدم للحصول على عدد العناصر الموجودة في Bucket محددة في الكائن الذي قام باستدعائها. مكان الباراميتر n نمرر عدد يمثل Index الـ Bucket التي سيتم إرجاع عدد العناصر الموجودة فيه. |
6 | size_t max_bucket_count() تستخدم للحصول على أكبر عدد Buckets يمكن تخزينها في الكائن الذي قام باستدعائها. |
7 | size_t bucket(key_type& k)
تستخدم للحصول على رقم Bucket محددة في الكائن الذي قام باستدعائها بالإعتماد على قيمة موجودة فيها. مكان الباراميتر k نمرر قيمة العنصر الذي نريد معرفة في Bucket موجود. |
الجدول التالي يحتوي على دوال الكلاس unordered_multiset التي تستخدم للتحكم بعناصره.
الدالة مع تعريفها | |
---|---|
1 | void emplace(T& val) تستخدم لإضافة عنصر جديد في الكائن الذي قام باستدعائها. |
2 | iterator erase(const_iterator position)
تستخدم لحذف عنصر محدد من الكائن الذي قام باستدعائها. مكان الباراميتر position نمرر كائن أصله من Iterator يشير لعنوان العنصر الذي سيتم حذفه. |
3 | iterator erase(const_iterator first, const_iterator last)
تستخدم لحذف مجموعة عناصر من الكائن الذي قام باستدعائها. مكان الباراميتر first نمرر كائن أصله من const_iterator يشير لعنوان العنصر الذي سيتم بدء الحذف من عنده.مكان الباراميتر last نمرر كائن أصله من const_iterator يشير لعنوان العنصر الذي سيتم إيقاف الحذف عنده. |
4 | void swap(unordered_multiset& anotherSet)
تستخدم لتبديل قيم عناصر الكائن الذي قام باستدعائها بقيم عناصر الكائن الذي نمرره لها. مكان الباراميتر anotherSet نمرر لها كائن من الكلاس unordered_multiset يملك نفس نوع عناصر الكائن الذي قام باستدعائها. |
الجدول التالي يحتوي على دوال الكلاس unordered_multiset التي تستخدم للبحث فيه.
الدالة مع تعريفها | |
---|---|
1 | size_t count(T& val)
تستخدم للبحث في الكائن الذي قام باستدعائها عن عدد العناصر التي تملك قيمة محددة. مكان الباراميتر val نمرر القيمة التي نريد البحث عنها. |
2 | iterator find(const T& val)
تستخدم للبحث في الكائن الذي قام باستدعائها عن أول عنصر يملك قيمة محددة. مكان الباراميتر val نمرر القيمة التي نريد البحث عنها.في حال تم إيجاد عنصر يملك نفس القيمة التي تم تمريرها لها ترجع كائن من Iterator يشير لعنوان العنصر في الذاكرة.و في حال لم يتم إيجاد عنصر يملك نفس القيمة التي تم تمريرها لها ترجع كائن من Iterator قيمته تساوي القيمة التي ترجعها الدالة end(). |
أمثلة شاملة حول التعامل مع الكلاس unordered_multiset
في كل مثال موضوع قمنا باستخدام دوال جديدة حتى تعرف كيف تستخدم جميع الدوال التي ذكرناها في الجدول.
في المثال التالي قمنا بتعريف كائن من unordered_multiset مع تحديد أنه يمكن أن يحتوي على عناصر نوعها string.
بعدها قمنا بإضافة بعض العناصر فيه و من ثم طباعة كم Bucket تم إنشاؤها و إجمالي عدد العناصر التي قمنا بإضافتها.
بعدها قمنا بعرض جميع قيم العناصر الموجودة فيه بواسطة حلقة.
ملاحظة: قمنا باستخدام الدالة emplace() لإضافة العناصر, الدالة bucket_count() لمعرفة كم Bucket تم إنشاؤها بشكل تلقائي, الدالة size() لمعرفة عدد العناصر التي تم إضافتها. عند عرض جميع قيم عناصر الكائن, قمنا باستخدام الدالة begin() للحصول على مؤشر للعنصر الأول لأننا سنبدأ من عنده و الدالة end() للحصول على مؤشر للعنصر الأخير لأننا سنتوقف عنده.
المثال الأول
سنحصل على النتيجة التالية عند التشغيل.
ums total buckets = 17 ums total elements = 9 ums values = Sun Tue Wed Thu Thu Fri Fri Mon Sat
في المثال التالي قمنا بتعريف كائن من unordered_multiset مخصص لتخزين قيم نوعها string مع إضافة عدة قيم فيه عند تعريفه.
بعدها قمنا بعرض القيم الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.
ملاحظة: قمنا باستخدام الدالة bucket_count() لمعرفة كم Bucket تم إنشاؤها بشكل تلقائي و الدالة bucket_size() لمعرفة عدد العناصر الموجودة في كل Bucket.
المثال الثاني
سنحصل على النتيجة التالية عند التشغيل.
bucket[0] elements: Fri bucket[1] elements: bucket[2] elements: Sat Mon bucket[3] elements: bucket[4] elements: Sun Wed bucket[5] elements: bucket[6] elements: bucket[7] elements: Tue bucket[8] elements: bucket[9] elements: bucket[10] elements: Thu
في المثال التالي قمنا بتعريف كائن من unordered_multiset مخصص لتخزين قيم نوعها string مع إضافة عدة قيم فيه عند تعريفه.
بعدها قمنا بعرض القيم الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.
ملاحظة: قمنا باستخدام الدالة bucket_count() لمعرفة كم Bucket تم إنشاؤها بشكل تلقائي, الدالة size() لمعرفة عدد العناصر التي تم إضافتها. عند عرض قيم العناصر الموجودة في كل Bucket قمنا باستخدام الدالة begin() للحصول على مؤشر للعنصر الأول فيها لأننا سنبدأ من عنده و الدالة end() للحصول على مؤشر للعنصر الأخير فيها لأننا سنتوقف عنده.
المثال الثالث
سنحصل على النتيجة التالية عند التشغيل.
bucket[0] total elements = 1 bucket[1] total elements = 0 bucket[2] total elements = 2 bucket[3] total elements = 0 bucket[4] total elements = 2 bucket[5] total elements = 0 bucket[6] total elements = 0 bucket[7] total elements = 1 bucket[8] total elements = 0 bucket[9] total elements = 0 bucket[10] total elements = 1
في المثال التالي قمنا بتعريف كائن من unordered_multiset مخصص لتخزين قيم نوعها string مع إضافة عدة قيم فيه عند تعريفه.
بعدها قمنا بالبحث عن قيم محددة فيه لمعرفة كم عنصر يملك هذه القيم.
ملاحظة: قمنا باستخدام الدالة count() لمعرفة كم مرة القيم مكررة في الكائن.
المثال الرابع
سنحصل على النتيجة التالية عند التشغيل.
'Apple' is exist 2 time(s) 'Carrot' is exist 0 time(s)
في المثال التالي قمنا بتعريف كائن من unordered_multiset مخصص لتخزين قيم نوعها string مع إضافة عدة قيم فيه عند تعريفه.
بعدها قمنا بالبحث عن أول عنصر يملك قيمة محددة فيه و في حال كانت موجودة سنقوم بحذف العنصر الذي يملكها من الكائن.
ملاحظة: قمنا باستخدام الدالة find() للبحث عن القيمة في الكائن و الدالة erase() لحذف العنصر من الكائن.
المثال الخامس
سنحصل على النتيجة التالية عند التشغيل.
First element with value 'Wed' is removed from ums ums values = Fri Thu Sun Tue Sat Mon
في المثال التالي قمنا بتعريف كائنين من unordered_multiset مع تحديد أنه يمكن أن يحتويان على عناصر نوعها int.
بعدها قمنا بتبديل عناصرهما و من ثم طباعة القيم التي أصبحت موجودة في كلٍّ منهما.
ملاحظة: قمنا باستخدام الدالة swap() لتبديل قيمهما.
المثال السادس
سنحصل على النتيجة التالية عند التشغيل.
ums1 values = 8 7 6 5 ums2 values = 4 3 2 1
في المثال التالي قمنا بتعريف كائن من unordered_multiset مخصص لتخزين قيم نوعها int مع تحديد الطريقة التي سيتم على أساسها توزيع القيم في Buckets و إضافة عدة قيم فيه عند تعريفه.
لتحديد الطريقة التي سيتم على أساسها توزيع القيم في Buckets قمنا بإنشاء كلاس إسمه Hash و إعادة تعريف العامل () حتى يقارن قيمة أي عنصر نريد إضافته نسبةً لعدد الأحرف الموجودة فيه, عندها يتم وضع الأعداد التي تتألف من رقم واحد في Bucket, و الأعداد التي تتألف من رقم رقمين في Bucket, و الأعداد التي تتألف من ثلاثة أعداد في Bucket و هكذا..
في النهاية قمنا بعرض القيم الموجودة في كل Bucket فيه بواسطة حلقتين متداخلتين.
المثال السابع
سنحصل على النتيجة التالية عند التشغيل, و لاحظ كيف تم ترتيب العناصر على أساس عدد الأرقام التي يتألف منها كل عنصر.
bucket[0] elements: bucket[1] elements: 1 3 6 bucket[2] elements: 55 72 34 bucket[3] elements: 100 123 bucket[4] elements: 2020 bucket[5] elements: bucket[6] elements: bucket[7] elements: bucket[8] elements: bucket[9] elements: bucket[10] elements: