




السمعة:
- إنضم22 يناير 2024
- المشاركات 229
- الحلول 3
- مستوى التفاعل 527
- النقاط 93
بسم الله الرحمن الرحيم
ستكون لنا اليوم الفرصة للتحدث عن مفهوم Recursion في البرمجة , لماذا اخترت التحدث عن هذا المفهوم خصيصًا؟
لأنك كمبرمج لا بد لك من التعرف على هذا المفهوم ولو بصفة سطحية لأننا نقع أحيانًا في مشاكل برمجية يكون حلها شبه مستحيل باستعمال sequent programming أو حتى Non recursive function
علينا أن نشير إلى أن معظم لغات البرمجة لديها هذا المفهوم مسبقًا لكن تبقى لغات قليلة جدًا لا تمتلك هذا المفهوم(Recursion not Implemented) كـ لغة Assembly مثلًا سيكون عليك تعريفها بنفسك كباقي المفاهيم في assembly التي تعتبر غير معرفة من قَبل كالـ Loops/function وغيرها
مفهوم الـ Recursion
هي ببساطة طريقة تفكير غير اعتيادية عليك اكتسابها , فلو طلب منك على سبيل المثال أن تجمع الخمس الأرقام الأولى فستفكر وببساطة بالجمع التتابعي التالي: 5+4+3+2+1
لكن أيفكر أحدكم بالجمع التتابعي التالي : 1+2+3+4+5
أكاد أُجزم أنه لن يفكر أحد فينا بهذه الطريقة لأنه وببساطة لم نعتد على طريقة تفكير مشابهة (أنا على الأقل لم أكن لأفكر بذلك

لنأخذ وضعية ثانية (لن نقدم مثال بالأكل؛ لأنه طلب منا عدم فعل ذلك أوقات الصيام

مع أوقات الصيام والكل في انتظار الأذان من أجل الأفطار يسألك والدك فجأة هل الفطور جاهز؟ وأنت تقوم لتسأل الوالدة الكريمة فتجد أخوك الصغير في الطريق فتقول له أن بسأل عن الفطور فيذهب ليسأل ثم يعود ويقول نعم جاهز وأنت تذهب لتخبر والدك (تخيل هذه الوضعية لأننا سنستخدمها فيما بعد )
لناخذ مثال عملي سريع وبسيط وهو المثال المشهور حساب Factoriel (عاملي n! )
مع أنه مثال سيظلم مفهوم Recursion لأنك لن ترى محظ الأثر في استخدامه لكن ومع ذلك سنستعمله لخدمة الفهم لأنه بسيط (يمكنك رؤية الأثر في Binary trees/trees عمومًا حينها ستدرك أن الحل يكاد يكون مستحيل بغيرها )
لناخذ N=5 (مع التذكير أن العاملي يحسب فقط للقيم الموجبة )
C++:
int i,s=1;
for(i=2;i<=5;++){
s=s*i ;
}
cout<<"The factoriel of 5 is"<<s;
أما باستخدام مفهوم الـ Recursion سنفكر بشي آخر وهو: أننا نبدأ في العد لكن دون معرفة الجواب , ماذا يعني ذلك ؟
في الوضعية السابقة من يملك جواب: 'الفطور جاهز؟ ' الوالدة الكريمة أليس كذلك فلو لم تكن الوالدة في المطبخ سيضطر أخوك الصغير أن يبحث عنها كي يحصل على الجواب وعندما يجدها يتوقف عن البحث فيأخذ الجواب لكن أنت لم يصلك الجواب بعد فيخبرك ولم يصل الجواب لوالدك بعد في نهاية ستخبره أن الفطور جاهز .
في النهاية لو الوالدة كانت تصلي على سبيل المثال لن يأخذ أي واحد منكم الجواب لحين انتهاءها , فهنا الشرط الأساسي وجود الوالدة حفظها الله , فلو تخيلنا هذه الوضعية ستعطينا بالضبط هذا الكود :
C++:
int factorial(int n) {
if(n > 1)
return n * factorial(n - 1);
else
return 1;
}

ماذا عن factoriel(1) نحن نعرف مسبقا أن factoriel(1)=1 ( هنا أخوك سأل الوالدة فهي تعرف الجواب) .
لو لم نضع الشرط سنقع في infinit loop (أخوك يبحث عن والدتك لكنه لا يجدها ) يبقي لنا فقط إرجاع النتيجة (الجواب للوالد) والنتيجة للـ function التي طلبت الجواب , في حالة استعمالنا الـ recursion ليس عليك القلق أين يجب عليك تخزين النتيجة ففي حال استخدامنا للـ loop for كنا قد خزنّا النتيجة في Variable S ومن ثم عرضها
أما في الحالة الثانية ستقوم function factoriel باستخدام stack لتخزين الخطوات ثم في حالة الوصول لشرط التوقف (n=1) ستقوم بالحساب والاحتفاظ بالنتيجة النهائية
جعلنا الله وإياكم ممن صدقوا فنالوا
