الخرائط (Maps)

map هو حاوية في C++ تقوم بتخزين أزواج من العناصر بهذا الشكل:

key -> value

وتقوم بترتيبها حسب المفتاح تلقائيًا.

مثال:

#include <iostream>
#include <map>
using namespace std;

int main() {
    map<string, int> ages;

    ages["Alice"] = 25;
    ages["Bob"] = 30;
    ages["Charlie"] = 22;

    for (auto p : ages)
        cout << p.first << ": " << p.second << endl;
}

الناتج:

Alice: 25
Bob: 30
Charlie: 22

لاحظ أن الأسماء مطبوعة بالترتيب الأبجدي — لأن map يقوم بترتيب المفاتيح تلقائيًا.

إنشاء خريطة (Creating a map)

لاستخدام الخريطة، قم بتضمين:

#include <map>

ثم يمكنك إعلانها هكذا:

map<int, string> students;     // المفتاح: int، القيمة: string
map<string, double> prices;    // المفتاح: string، القيمة: double
map<char, int> frequency;      // المفتاح: char، القيمة: int

إضافة والوصول للعناصر

map<string, int> scores;

scores["Mark"] = 90;          // الإضافة باستخدام [] 

cout << scores["Mark"];       // يطبع 90

إذا حاولت الوصول لمفتاح غير موجود باستخدام []، سيتم إنشاؤه تلقائيًا بقيمة افتراضية (مثل 0).

cout << scores["Unknown"];  // ينشئ "Unknown" بقيمة 0

إذا كنت لا تريد هذا السلوك، استخدم count() للتحقق أولًا من وجود المفتاح.

if (scores.count("Tom"))
    cout << "Tom found!";

العمليات الشائعة

العملية المثال الوصف
m[key] m["Bob"] الوصول إلى العنصر أو إنشاؤه
erase(key) m.erase("Bob") إزالة المفتاح والقيمة
count(key) if (m.count("Bob")) 1 إذا كان المفتاح موجود، 0 إذا لم يكن
size() m.size(); إعادة عدد العناصر
clear() m.clear(); حذف جميع العناصر
empty() m.empty(); التحقق مما إذا كانت الخريطة فارغة

مثال: عد تكرار الكلمات

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    string text = "apple banana apple orange banana apple";
    map<string, int> freq;

    string word;
    for (auto c : text) {
        if (c == ' ') {
            if (!word.empty()) freq[word]++;
            word.clear();
        } else {
            word += c;
        }
    }
    if (!word.empty()) freq[word]++; // آخر كلمة

    for (auto p : freq)
        cout << p.first << ": " << p.second << endl;
}

الناتج:

apple: 3
banana: 2
orange: 1

التكرار عبر الخريطة

يمكنك التكرار باستخدام حلقة for بنطاق:

for (auto p : myMap)
    cout << p.first << " -> " << p.second << endl;

أو باستخدام المؤشرات (iterators):

for (auto it = myMap.begin(); it != myMap.end(); it++)
    cout << it->first << ": " << it->second << endl;

first = المفتاح، second = القيمة.

أنواع الخرائط

النوع يحافظ على الترتيب؟ يسمح بالمفاتيح المكررة؟ السرعة (متوسط) ملاحظات
map نعم لا O(log n) يخزن المفاتيح مرتبة (شجرة متوازنة)
unordered_map لا لا O(1) متوسط سريع، لكن الترتيب عشوائي

مثال: unordered_map

#include <iostream>
#include <unordered_map>
using namespace std;

int main() {
    unordered_map<string, int> age;

    age["Bob"] = 30;
    age["Alice"] = 25;
    age["Tom"] = 28;

    for (auto p : age)
        cout << p.first << ": " << p.second << endl;
}

الناتج:

(الترتيب قد يكون عشوائي)
Bob: 30
Tom: 28
Alice: 25

لذلك unordered_map عادة أسرع، لكنه لا يقوم بترتيب المفاتيح.