Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

حاويات STL

جزء من قسم البرمجة كائنية التوجه في رحلة C++ على Coddy. الدرس 71 من 104.

تُعد STL containers فئات template تُخزّن مجموعات من الكائنات وتنظّمها. كل نوع من أنواع الحاويات مُحسّن لأنماط access والعمليات المختلفة. ويمكن لاختيار الحاوية المناسبة لاحتياجاتك أن يؤثر بشكل كبير في أداء برنامجك.

حاويات التسلسل تحافظ على العناصر بترتيب محدد:

#include <vector>
#include <list>

std::vector<int> vec = {1, 2, 3};  // مصفوفة ديناميكية، وصول عشوائي سريع
vec.push_back(4);                   // إضافة إلى النهاية: O(1) مُطفأ
int x = vec[2];                     // الوصول بالفهرس: O(1)

std::list<int> lst = {1, 2, 3};    // قائمة مرتبطة مضاعفة
lst.push_front(0);                  // إضافة إلى الأمام: O(1)
lst.push_back(4);                   // إضافة إلى النهاية: O(1)

الحاويات الترابطية تخزّن العناصر بترتيب مُرتَّب لإجراء بحث سريع:

#include <map>
#include <set>

std::set<int> s = {3, 1, 4, 1};    // عناصر فريدة مرتبة: {1, 3, 4}
s.insert(2);                        // إدراج: O(log n)
bool found = s.count(3);            // التحقق من الوجود: O(log n)

std::map<std::string, int> ages;   // أزواج مفتاح-قيمة، مرتبة حسب المفتاح
ages["Alice"] = 25;                 // إدراج/تحديث: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"];        // الوصول: O(log n)

containers غير المرتبة تستخدم جداول التجزئة لعمليات بحث أسرع في الحالة المتوسطة:

#include <unordered_map>

std::unordered_map<std::string, int> scores;
scores["player1"] = 100;            // إدراج: O(1) متوسط
scores["player2"] = 200;
std::cout << scores["player1"];    // وصول: O(1) متوسط

استخدم vector عندما تحتاج إلى وصول عشوائي سريع، وlist للإدراجات المتكررة في الوسط، وmap/set عندما تحتاج إلى بيانات مرتبة، وunordered_map عندما تكون سرعة البحث أمرًا بالغ الأهمية ولا يهم الترتيب.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لإدارة درجات الطلاب يوضّح كيفية خدمة حاويات STL المختلفة لأغراض مختلفة. ستستخدم أنواعًا متعددة من الحاويات لتنظيم بيانات الطلاب بكفاءة، مع اختيار الحاوية المناسبة لكل مهمة.

ستنشئ ملفين لتنظيم التعليمات البرمجية:

  • GradeManager.h: Define فئة GradeManager تستخدم حاويات STL متعددة لإدارة معلومات الطلاب.

    يجب أن تستخدم فئتك:

    • std::vector<std::string> لتخزين أسماء الطلاب بالترتيب الذي تمت فيه إضافتهم
    • std::map<std::string, int> لربط اسم كل طالب بدرجته
    • std::set<int> لتتبّع جميع الدرجات الفريدة التي تم تعيينها

    Implement هذه الدوال:

    • addStudent(const std::string& name, int grade): تضيف طالبًا مع درجته إلى الحاويات الثلاث جميعًا
    • getGrade(const std::string& name): تُرجع درجة طالب given باستخدام الخريطة
    • printRoster(): تطبع جميع أسماء الطلاب بالترتيب الذي تمت فيه إضافتهم (من المتجه)، بحيث يظهر كل اسم في سطر جديد
    • printGrades(): تطبع جميع الطلاب مع درجاتهم بترتيب alphabetical (تتولى الخريطة ذلك تلقائيًا)، بتنسيق name: grade في كل سطر
    • printUniqueGrades(): تطبع جميع الدرجات الفريدة بترتيب ascending (تتولى المجموعة ذلك)، مفصولة بمسافات يتبعها سطر جديد
  • main.cpp: اقرأ المدخلات ووضّح كيفية خدمة كل نوع من الحاويات لغرض مختلف.

    اقرأ ستة مدخلات (كل منها في سطر منفصل):

    1. اسم الطالب الأول
    2. درجة الطالب الأول (عدد صحيح)
    3. اسم الطالب الثاني
    4. درجة الطالب الثاني (عدد صحيح)
    5. اسم الطالب الثالث
    6. درجة الطالب الثالث (عدد صحيح)

    أنشئ كائنًا من GradeManager وأضف الطلاب الثلاثة جميعًا. ثم وضّح سلوكيات الحاويات المختلفة:

    1. اطبع Roster (insertion order): ثم استدعِ printRoster()
    2. اطبع Grades (alphabetical): ثم استدعِ printGrades()
    3. اطبع Unique grades: ثم استدعِ printUniqueGrades()
    4. ابحث عن درجة الطالب الثاني واطبع <name>'s grade: <grade>

على سبيل المثال، باستخدام المدخلات Charlie و85 وAlice و90 وBob و85:

Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90 
Alice's grade: 90

لاحظ كيف يحافظ المتجه على ترتيب الإدراج (Charlie وAlice وBob)، بينما ترتّب الخريطة المفاتيح تلقائيًا (Alice وBob وCharlie)، وتخزّن المجموعة القيم الفريدة فقط بترتيب مرتب (تظهر 85 مرة واحدة، وليس مرتين). يتفوّق كل نوع من الحاويات في مهام مختلفة!

جرّب بنفسك

#include <iostream>
#include <string>
#include "GradeManager.h"

using namespace std;

int main() {
    // اقرأ المدخلات لثلاثة طلاب
    string name1, name2, name3;
    int grade1, grade2, grade3;
    
    cin >> name1;
    cin >> grade1;
    cin >> name2;
    cin >> grade2;
    cin >> name3;
    cin >> grade3;
    
    // TODO: أنشئ كائن GradeManager
    
    // TODO: أضف جميع الطلاب الثلاثة إلى GradeManager
    
    // TODO: Print "Roster (insertion order):" and call printRoster()
    
    // TODO: Print "Grades (alphabetical):" and call printGrades()
    
    // TODO: Print "Unique grades:" and call printUniqueGrades()
    
    // TODO: ابحث عن درجة الطالب الثاني واطبع "<name>'s grade: <grade>"
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C++ عبر الإنترنت