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

خوارزميات STL

جزء من قسم Object Oriented Programming في رحلة C++ على Coddy — الدرس 73 من 104.

تُعد خوارزميات STL دوال قالبية (template functions) تعمل على نطاقات محددة بواسطة المكررات (iterators). وهي موجودة في الترويسات <algorithm> و <numeric> وتعمل مع أي حاوية (container) توفر مكررات متوافقة.

std::sort يرتب العناصر بترتيب تصاعدي افتراضيًا:

#include <algorithm>
#include <vector>

std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}

std::find يبحث عن قيمة ويعيد مكرراً (iterator) لأول تطابق، أو end() إذا لم يتم العثور عليها:

auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
    std::cout << "Found at index: " << (it - nums.begin());
}

std::transform يقوم بتطبيق عملية على كل عنصر ويخزن النتائج في نطاق الوجهة:

std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
               [](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}

std::accumulate من <numeric> يجمع كافة العناصر في قيمة واحدة:

#include <numeric>

int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum: 16 (1 + 2 + 5 + 8)

تقبل هذه الخوارزميات نطاقات المكررات (iterator ranges) بدلاً من الحاويات مباشرةً، مما يجعلها مرنة بما يكفي للعمل على نطاقات جزئية أو أنواع حاويات مختلفة باستخدام نفس الكود.

challenge icon

التحدي

سهل

لنقم ببناء محلل درجات (score analyzer) يعالج مجموعة من الأرقام باستخدام خوارزميات STL. ستقوم بإنشاء دوال مساعدة توضح كيفية عمل sort و find و transform و accumulate معاً لتحليل البيانات.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • ScoreAnalyzer.h: قم بتعريف دوال مساعدة تستخدم خوارزميات STL لمعالجة متجهات (vectors) من الأعداد الصحيحة.

    أنشئ دالة تسمى sortScores تأخذ std::vector<int>& وتقوم بفرزها بترتيب تصاعدي باستخدام std::sort.

    أنشئ دالة تسمى findScore تأخذ const std::vector<int>& وقيمة مستهدفة من نوع int. استخدم std::find للبحث عن القيمة المستهدفة. إذا تم العثور عليها، فقم بإرجاع الفهرس (المسافة من البداية). إذا لم يتم العثور عليها، فقم بإرجاع -1.

    أنشئ دالة تسمى applyBonus تأخذ const std::vector<int>& ومبلغ مكافأة (bonus) من نوع int. استخدم std::transform لإنشاء وإرجاع متجه جديد حيث يتم إضافة المكافأة إلى كل درجة.

    أنشئ دالة تسمى calculateAverage تأخذ const std::vector<int>& وترجع المتوسط كـ double. استخدم std::accumulate لحساب المجموع، ثم اقسمه على الحجم.

    أنشئ دالة تسمى printVector تأخذ const std::vector<int>& وتطبع جميع العناصر مفصولة بمسافات، متبوعة بسطر جديد.

  • main.cpp: اقرأ ستة مدخلات (كل منها في سطر منفصل):
    1. الدرجة الأولى (عدد صحيح)
    2. الدرجة الثانية (عدد صحيح)
    3. الدرجة الثالثة (عدد صحيح)
    4. الدرجة الرابعة (عدد صحيح)
    5. درجة للبحث عنها (عدد صحيح)
    6. مبلغ مكافأة لتطبيقه (عدد صحيح)

    أنشئ متجهاً بالدرجات الأربع واستعرض الخوارزميات:

    1. اطبع Original: متبوعاً بمحتويات المتجه
    2. قم بفرز الدرجات واطبع Sorted: متبوعاً بالمتجه المفرز
    3. ابحث عن الدرجة المستهدفة في المتجه المفرز. إذا تم العثور عليها، اطبع Found <value> at index <index>. إذا لم يتم العثور عليها، اطبع <value> not found
    4. طبق المكافأة على الدرجات المفرزة واطبع With bonus: متبوعاً بالمتجه الجديد
    5. احسب واطبع متوسط الدرجات المفرزة الأصلية (قبل المكافأة) كـ Average: <value> مع منزلة عشرية واحدة

على سبيل المثال، مع المدخلات 75، 90، 60، 85، 85، و 5:

Original: 75 90 60 85 
Sorted: 60 75 85 90 
Found 85 at index 2
With bonus: 65 80 90 95 
Average: 77.5

مع المدخلات 100، 80، 95، 70، 50، و 10:

Original: 100 80 95 70 
Sorted: 70 80 95 100 
50 not found
With bonus: 80 90 105 110 
Average: 86.2

تذكر تضمين <algorithm> من أجل sort و find و transform، و <numeric> من أجل accumulate. استخدم std::fixed و std::setprecision(1) من <iomanip> لتنسيق المتوسط.

ورقة مرجعية

خوارزميات STL هي دوال قالب (template functions) من <algorithm> و <numeric> تعمل على نطاقات محددة بواسطة المكررات (iterators).

تقوم std::sort بترتيب العناصر بترتيب تصاعدي:

#include <algorithm>
#include <vector>

std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}

تبحث std::find عن قيمة وتُرجع مكررًا (iterator) لأول تطابق، أو end() إذا لم يتم العثور عليها:

auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
    std::cout << "Found at index: " << (it - nums.begin());
}

تقوم std::transform بتطبيق عملية على كل عنصر وتخزين النتائج في نطاق وجهة (destination range):

std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
               [](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}

تقوم std::accumulate من <numeric> بدمج جميع العناصر في قيمة واحدة:

#include <numeric>

int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum: 16 (1 + 2 + 5 + 8)

تعمل هذه الخوارزميات مع نطاقات المكررات (iterator ranges)، مما يجعلها مرنة للنطاقات الجزئية أو أنواع الحاويات المختلفة.

جرّب بنفسك

#include <iostream>
#include <vector>
#include <iomanip>
#include "ScoreAnalyzer.h"

using namespace std;

int main() {
    // قراءة ستة مدخلات
    int score1, score2, score3, score4;
    int searchTarget, bonusAmount;
    
    cin >> score1;
    cin >> score2;
    cin >> score3;
    cin >> score4;
    cin >> searchTarget;
    cin >> bonusAmount;
    
    // TODO: إنشاء vector يحتوي على الدرجات الأربع
    
    // TODO: طباعة "Original:" متبوعة بمحتويات الـ vector
    
    // TODO: فرز الدرجات وطباعة "Sorted:" متبوعة بالـ vector المفرز
    
    // TODO: البحث عن الدرجة المستهدفة في الـ vector المفرز
    // إذا تم العثور عليها، اطبع "Found <value> at index <index>"
    // إذا لم يتم العثور عليها، اطبع "<value> not found"
    
    // TODO: تطبيق المكافأة (bonus) على الدرجات المفرزة وطباعة "With bonus:" متبوعة بالـ vector الجديد
    
    // TODO: حساب وطباعة متوسط الدرجات المفرزة (قبل المكافأة)
    // استخدم fixed و setprecision(1) للتنسيق
    // اطبعها كـ "Average: <value>"
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming