مضى على الشبكة و يوم من العطاء.

Day2-[tip2] -يوم[2] -فكرة[2]-فن الانعكاس والتراجع في البرمجةRecursion

MinaMina is verified member.

{ | مشرف قسم لغات البرمجة | }
.:: طاقم المشرفين ::.
.:: كاتب تقني ::.

السمعة:

بسم الله الرحمن الرحيم

ستكون لنا اليوم الفرصة للتحدث عن مفهوم 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 function تأخذ parameter (n) في حالتنا هي سؤال الوالد وفي المثال السابق 5=N , نحن لا نملك قيمة factoriel (5) ولا نملك الجواب , فسنضطر للسؤال عن factoriel(4) (سؤال شخص من الممكن أن يعرف الجواب) وسنضطر للسؤال عن factoriel(3) لأننا لا نملك الجواب مسبقًا ( يمكن أن أخاك سأل أختك في الطريق إلا أنها لا تعرف الجواب) فسنضطر للسؤال عن factoriel(2) لا نملك الجواب مسبقًا
ماذا عن factoriel(1) نحن نعرف مسبقا أن factoriel(1)=1 ( هنا أخوك سأل الوالدة فهي تعرف الجواب) .

لو لم نضع الشرط سنقع في infinit loop (أخوك يبحث عن والدتك لكنه لا يجدها ) يبقي لنا فقط إرجاع النتيجة (الجواب للوالد) والنتيجة للـ function التي طلبت الجواب , في حالة استعمالنا الـ recursion ليس عليك القلق أين يجب عليك تخزين النتيجة ففي حال استخدامنا للـ loop for كنا قد خزنّا النتيجة في Variable S ومن ثم عرضها

أما في الحالة الثانية ستقوم function factoriel باستخدام stack لتخزين الخطوات ثم في حالة الوصول لشرط التوقف (n=1) ستقوم بالحساب والاحتفاظ بالنتيجة النهائية


جعلنا الله وإياكم ممن صدقوا فنالوا 🤍
 
بسم الله الرحمن الرحيم
ستكون لنا اليوم الفرصة للتحدث عن مفهوم Recursion في البرمجة

لما اخترت التحدث عن هذا المفهوم خصيصاً ?

لانك كمبرمج لا بد لك من التعرف على هذا المفهوم ولو بصفة سطحية لاننا نقع احيانا في مشاكل برمجية يكون حلها شبه مستحيل باستعمال sequent programming او حتى Non recursive function


علينا ان نشير ان اغلب ومعظم لغات البرمجة لديها هذا المفهوم مسبقاً لكن تبقى لغات قليلة جدا لا تمتلك هذا المفهوم(Recursion not Implemented )

(كلغة Assembly مثلا سيكون عليك تعريفها بنفسك كباقي المفاهيم في assembly التي تعتبر غير معرفة من قبل كال Loops/function وغيرها)



مفهومها:

هي وببساطة طريقة تفكير غير اعتيادية عليك اكتسابها

فلو طلب منك على سبيل المثال ان تجمع الخمس الارقام الاولى فستفكر وببساطة بالجمع التتابعي التالي:

1+2+3+4+5


لكن ايفكر احدكم بالجمع التتابعي التالي :

5+4+3+2+1

اكاد اجزم انه لن يفكر احد فينا بهذه الطريقة لانه وببساطة لم نعتد على طريقة تفكير مشابهة (انا على الاقل لم اكن لافكر بذلك 😅 )

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

مع اوقات الصيام والكل في انتظار الاذان من اجل الافطار يسئلك ابوك فجأة الفطور جاهز ? وانت تقوم عشان تسأل الوالدة الكريمة فتجد اخوك الصغير في الطريق فتقولو يلا اسألي عن الفطور يروح يسال ويرجع بيقولك اه جاهز وهون تروح لتخبر ابوك(تخيل هاذي الوضعية لاننا سنستخدمها فيما بعد )

لناخذ مثال عملي سريع وبسيط وهو المثال المشهور حساب 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 function تاخذ parametre(n)
(n ) في حالتنا هي سوال الوالد وفي المثال السابق 5=N

نحن لا نملك قيمة factoriel 5(ولا نملك الجواب)

فسنظطر للسوال عن factoriel(4)(سوال شخص من الممكن ان يعرف الجواب)

فسنظطر للسوال عن factoriel(3) لانملك الجواب مسبقا ( يمكن ان اخاك سأل اختك في الطريق الا انها لا تعرف الجواب💁🏻‍♀️)

فسنظطر للسوال عن factoriel(2) لانملك الجواب مسبقا

ماذا عن factoriel(1) نحن نعرف مسبقا ان factoriel(1)=1 ( هنا اخوك سال الوالدة فهي تعرف الجواب😁)

لو لم نضع الشرط سنقع في infinit loop (اخوك بيضله يبحث ومش لاقي الوالدة )

يبقي لنا فقط ارجاع النتيجة (الجواب للوالد) والنتيجة لل function التي طلبت الجواب

في حالة استعمالنا لل recursion ليس عليك القلق اين يجب عليك تخزين النتيجة ففي حالة استخدامنا لل loop for كنا قد خزنا النتيجة في Variable s

ومن ثم عرضناها

اما في الحالة الثانية ستقوم function factoriel باستخدام stack لتخزين الخطوات ثم في حالة الوصول لشرط التوقف (n=1) ستقوم بالحساب والاستحفاظ بالنتيجة النهائية



جعلنا الله واياكم ممن صدقوا فنالوا 🤍
يعطيك العافية 🤍حبيت المثال😂😂
 
  • Love
التفاعلات: Mina
بسم الله الرحمن الرحيم

ستكون لنا اليوم الفرصة للتحدث عن مفهوم 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 function تأخذ parametre (n ) في حالتنا هي سؤال الوالد وفي المثال السابق 5=N , نحن لا نملك قيمة factoriel (5) ولا نملك الجواب , فسنضطر للسؤال عن factoriel(4) (سؤال شخص من الممكن أن يعرف الجواب) وسنضطر للسؤال عن factoriel(3) لأننا لا نملك الجواب مسبقًا ( يمكن أن أخاك سأل أختك في الطريق إلا أنها لا تعرف الجواب) فسنضطر للسؤال عن factoriel(2) لا نملك الجواب مسبقًا
ماذا عن factoriel(1) نحن نعرف مسبقا أن factoriel(1)=1 ( هنا أخوك سأل الوالدة فهي تعرف الجواب) .

لو لم نضع الشرط سنقع في infinit loop (أخوك يبحث عن والدتك لكنه لا يجدها ) يبقي لنا فقط إرجاع النتيجة (الجواب للوالد) والنتيجة للـ function التي طلبت الجواب , في حالة استعمالنا الـ recursion ليس عليك القلق أين يجب عليك تخزين النتيجة ففي حال استخدامنا للـ loop for كنا قد خزنّا النتيجة في Variable S ومن ثم عرضها

أما في الحالة الثانية ستقوم function factoriel باستخدام stack لتخزين الخطوات ثم في حالة الوصول لشرط التوقف (n=1) ستقوم بالحساب والاحتفاظ بالنتيجة النهائية


جعلنا الله وإياكم ممن صدقوا فنالوا 🤍
يعطيكِ ألف عافية يا رب
 
  • Love
التفاعلات: Mina
بارك الله فيك على هذا الطرح الجميل والتوضيح المبهر، استمري 🔥
 
  • Love
التفاعلات: Mina

آخر المشاركات

فانوس

رمضان
عودة
أعلى