المضروب بالاستدعاء الذاتي
جزء من قسم Logic & Flow في رحلة C++ على Coddy — الدرس 46 من 56.
يعد مضروب العدد مثالاً مثالياً لتوضيح مفهوم العودية (recursion) بشكل عملي. مضروب n (الذي يُكتب n!) هو حاصل ضرب جميع الأعداد الصحيحة الموجبة من 1 إلى n. على سبيل المثال، 5! = 5 × 4 × 3 × 2 × 1 = 120.
ما يجعل المضروب (factorial) مثالياً للاستدعاء الذاتي (recursion) هو أنه يمكن تعريفه بدلالة نفسه: n! = n × (n-1)!. وهذا يعني أنه لحساب !5، تضرب 5 في !4، ولحساب !4، تضرب 4 في !3، وهكذا.
إليك كيف تبدو دالة المضروب (factorial) العودية:
int factorial(int n) {
if (n <= 1) { // الحالة الأساسية: !0 و !1 كلاهما يساوي 1
return 1;
}
return n * factorial(n - 1); // الخطوة العودية: !n! = n × (n-1)
}تتوقف الحالة الأساسية عن الاستدعاء الذاتي عندما تصل n إلى 1 أو 0، مع إرجاع 1. تقوم الخطوة الاستدعائية بضرب الرقم الحالي في مضروب الرقم الأصغر التالي. عندما تستدعي factorial(4)، فإنه يحسب 4 × 3 × 2 × 1 عن طريق إجراء استدعاءات متتالية حتى يصل إلى الحالة الأساسية، ثم يضرب جميع النتائج معاً عند عودة الاستدعاءات.
التحدي
سهلقم بإنشاء برنامج ينفذ دالة عاملي (factorial) تكرارية ويستخدمها لحساب العاملي لقيم مدخلات مختلفة. سيختبر هذا التحدي فهمك لكيفية عمل التكرار (recursion) من خلال جعل الدالة تستدعي نفسها بمعاملات معدلة حتى تصل إلى حالة أساسية (base case).
سيتم توفير المدخلات التالية:
- عدد صحيح
nيمثل الرقم الذي سيتم حساب العاملي له
يجب أن يقوم برنامجك بما يلي:
- إنشاء دالة تكرارية تسمى
factorialتأخذ معاملاً صحيحاً وتعيد عدداً صحيحاً - يجب أن تنفذ الدالة الحالة الأساسية: إذا كانت
nأقل من أو تساوي 1، فقم بإرجاع 1 - يجب أن تنفذ الدالة الخطوة التكرارية: إرجاع
nمضروباً في عامليn-1 - في الدالة الرئيسية، اقرأ قيمة المدخلات
- استدعِ دالة factorial مع قيمة المدخلات
- اطبع النتيجة باستخدام التنسيق المحدد
استخدم تنسيق المخرجات الدقيق التالي:
Factorial of [n] is [result]تذكر أن دالة factorial يجب أن تستدعي نفسها بقيمة أصغر في كل مرة، لتقترب من الحالة الأساسية مع كل استدعاء تكراري. تمنع الحالة الأساسية التكرار اللانهائي بالتوقف عندما تصل n إلى 1 أو 0. تضرب الخطوة التكرارية الرقم الحالي في عاملي الرقم الأصغر التالي، مما يؤدي إلى بناء النتيجة النهائية مع عودة قيم استدعاءات الدالة.
ورقة مرجعية
مضروب العدد n (أو !n) هو حاصل ضرب جميع الأعداد الصحيحة الموجبة من 1 إلى n. ويمكن تعريفه بشكل تكراري (recursively) كالتالي: n! = n × (n-1)!
دالة المضروب التكرارية (Recursive factorial function):
int factorial(int n) {
if (n <= 1) { // الحالة الأساسية: !0 و !1 كلاهما يساوي 1
return 1;
}
return n * factorial(n - 1); // الخطوة التكرارية: n! = n × (n-1)!
}توقف الحالة الأساسية (base case) عملية التكرار عندما تصل قيمة n إلى 1 أو 0. وتقوم الخطوة التكرارية بضرب الرقم الحالي في مضروب الرقم الأصغر التالي.
جرّب بنفسك
#include <iostream>
using namespace std;
// مهام: اكتب دالة المضروب (factorial) هنا
int main() {
// قراءة المدخلات
int n;
cin >> n;
// مهام: استدعِ دالة المضروب وقم بتخزين النتيجة
// طباعة النتيجة
cout << "Factorial of " << n << " is " << result << endl;
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1المؤشرات والذاكرة
ما هو المؤشر؟معامل العنوان (Address-Of)معامل الوصول للقيمة (Dereference)المؤشرات الفارغة (Null Pointers)المؤشرات والمصفوفاتالذاكرة الديناميكية باستخدام 'new'تحرير الذاكرة باستخدام 'delete'مراجعة - تمارين على المؤشرات4الخرائط (أزواج مفتاح-قيمة)
مقدمة إلى std::mapإنشاء خريطةالوصول إلى القيم وتعديلهاالتحقق من وجود المفاتيححذف الأزواجالتكرار عبر الخريطةمراجعة - تكرار الكلمات7الدوال المتقدمة
التمرير بالمرجعمقدمة في تعبيرات Lambdaتعبيرات Lambda مع المعاملاتتعبيرات Lambda مع قيم الإرجاعمقدمة في الاستدعاء الذاتيالمضروب بالاستدعاء الذاتيالفرز باستخدام Lambda2المتجهات (المصفوفات الديناميكية)
مقدمة إلى std::vectorإنشاء Vectorإضافة العناصرالوصول إلى العناصرحجم الـ Vectorالتكرار باستخدام For Loopالـ Range-Based For Loopإزالة العناصرملخص - عمليات الـ Vector