أجهزة الكمبيوتر شبابيك إنترنت

دالة تقوم بإرجاع مضروب php. دروس PHP. العودية. هذا بسبب واحد

يدور هذا البرنامج التعليمي حول العودية في PHP. يمكنك استدعاء وظيفة أخرى من داخل الوظيفة. يمكن للبرنامج استدعاء الوظيفة f1 () ، التي تستدعي الوظيفة f2 () ، وهكذا. الوظيفة التي تستدعي نفسها تسمى العودية. هذا النوع من العودية يسمى العودية الصريحة. إذا كانت الوظيفة f1 () تستدعي وظيفة أخرى f2 () ، والتي بدورها تستدعي الوظيفة f1 () ، فإن هذه الوظائف تكون عودية أيضًا. هذا النوع من العودية يسمى العودية الضمنية. من الواضح أن الأشكال الأكثر تعقيدًا من العودية الضمنية ممكنة.

افترض أنك بحاجة إلى إنشاء دالة تعاودية لحل بعض المشاكل. في هذا الدرس ، سنصف إحدى الاستراتيجيات المعروفة لحل مشكلة ما باستخدام دالة تكرارية. تنقسم عملية حل المشكلة بشكل متكرر إلى مراحل. في الخطوة الأولى ، يتم استدعاء دالة تكرارية لحل المشكلة. هذه الوظيفة تحل المشكلة لأبسط المواقف. يُطلق على أبسط موقف لمشكلة معينة مشكلة أساسية. إذا تم استخدام دالة لحل مشكلة أساسية ، فإنها ترجع حلاً أو نتيجة.

إذا تم استدعاء دالة لحل مشكلة أكثر تعقيدًا من المشكلة الأساسية ، فإن الوظيفة تقسم المشكلة إلى قسمين:

  • الجزء 1 أن الوظيفة يمكن حلها ؛
  • الجزء 2 أن الدالة لا تستطيع حلها.

لتطبيق العودية ، يجب أن يكون الجزء 2 مشابهًا للمشكلة الأولية ، لكن أصغر نسبيًا أو أبسط.

نظرًا لأن المهمة التي تم إنشاؤها في الجزء 2 تشبه المهمة الأولية ، فإن الوظيفة تستدعي مثيلًا جديدًا خاصًا بها لمعالجة المهمة الجديدة. يسمى هذا الإجراء استدعاء متكرر أو خطوة عودية.

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

لإكمال العودية ، يجب أن تشكل الوظيفة العودية سلسلة من المهام المبسطة (المتناقصة) التي تقترب من المهمة الأساسية. عندما تكتشف الوظيفة ، في خطوة ما من العودية ، المشكلة الأساسية ، فإنها تُرجع الحل (النتيجة) للمشكلة الأساسية في الاستدعاء السابق (الخطوة السابقة من العودية). في هذه الاستدعاء ، يتم دمج النتيجة مع الجزء الذي يمكن أن تحله الوظيفة. الحل المتشكل بهذه الطريقة يعود خطوة واحدة ، وهكذا. يؤدي هذا إلى إنشاء النتيجة الأخيرة وإعادتها إلى نقطة البداية لاستدعاء الدالة العودية. أي ، لكي تتمكن من العودة ، يجب أن تُبنى كل خطوة من خطوات الوظيفة بطريقة تحتوي على الكلمة المحجوزة return.

لتوضيح الفكرة أعلاه ، إليك مثال على استخدام دالة تكرارية.

مثال 1. عاملي. معامل العدد الصحيح غير السالب n هو n * (n-1) * (n-2) * ... 2 * 1 ويُرمز له بـ n!. من المفترض أن 1! = 1 و 0! = 1. على سبيل المثال ، 7! = 7 * 6 * 5 * 4 * 3 * 2 * 1 = 5040.

الحل التكراري (غير العودي) لحساب العامل هو كما يلي (ملف factorial1.php):



عاملي



حساب العامل



Adadi Naturali (ن> = 0):





";
خروج؛
}
دولار و = 1 ؛
لـ ($ i = $ n ؛ $ i> = 1 ؛ $ i--)
$ f * = $ i ؛
صدى "$ n! = $ f"؛
?>

دع f (n) = n! ، إذن
و (ن) = ن! = ن * (س -1)! = ن * و (ن -1) ،
أي أن الصيغة العودية لحساب العامل هي:
و (ن) = ن * و (ن -1).

مثال:
f (5) = 5 * f (4) = 5 * 4 * f (3) = 5 * 4 * 3 * f (2) = 5 * 4 * 3 * 2 * f (1) = 5 * 4 * 3 * 2 * 1 = 120.

بناءً على الصيغة العودية ، دعنا نؤلف دالة تعاودية لحساب العامل (file factorial2.php):



عاملي



حساب العامل



Adadi Naturali (ن> = 0):




إذا (! isset ($ _ GET ["n"]) || ($ n = $ _GET ["n"]) == "") (
صدى "الرجاء إدخال رقم طبيعي!
";
خروج؛
}
$ f = مضروب ($ n) ؛
صدى "$ n! = $ f"؛

عامل عاملي ($ i) (
إذا ($ i<2) return 1;
$ k = $ i * عاملي ($ i-1) ؛
إرجاع $ k؛
}

?>

إذا أدخلت الرقم 5 في البرنامج ، فاحسب 5! يعمل البرنامج على النحو التالي:

يتحقق الاستدعاء الأول للدالة المضروبة () مما إذا كان الرقم المرسل إلى الوظيفة أقل من 2. إذا كان الرقم الذي تتلقاه الوظيفة هو 2 على الأقل ، فإن المشكلة أكبر أو أكثر تعقيدًا من المشكلة الأساسية ، وبالتالي ، تنقسم المشكلة إلى قسمين:

  1. $ k = $ i * - الجزء 1 الذي يمكن أن تحله الوظيفة ؛
  2. العامل ($ n-1) هو الجزء 2 الذي لا تستطيع الدالة حله.

يتكرر هذا الإجراء حتى يتم استلام المهمة الأساسية ، أي حتى يتم استدعاء العامل (1). إذا كان الرقم أقل من 2 (1 أو 0) ، فإن دالة العامل () ترجع الرقم 1 ($ k = 1) ، أي أن المشكلة الأساسية قد تم حلها. إذا تم استدعاء مثيل العامل () في وقت سابق من خلال مثيل آخر للعامل () ، فسيتم إرجاع النتيجة إلى مثيل استدعاء الوظيفة. هناك يتم ضرب النتيجة التي تم إرجاعها $ k بالمعامل $ n الذي يتم تمريره إلى الوظيفة ويتم تعيينه إلى $ k. إذا تم استدعاء مثيل الوظيفة العامل () في وقت سابق من خلال مثيل آخر للدالة المضروبة () ، فعندئذٍ يتم إرجاع النتيجة إلى مثيل استدعاء الوظيفة ويتم تكرار العملية الموصوفة. إذا تم استدعاء مثيل الدالة Factial () من الجزء الرئيسي للبرنامج ، فسيتم إرجاع $ k إلى هذا الجزء ، حيث يتم عرض النتيجة على الشاشة وينتهي البرنامج.

"العودية

تصفح البرنامج التعليمي: 1.1 نبذة عن PHP 1.2 تاريخ PHP 1.3 لماذا PHP؟ 1.4 كيف يعمل كل شيء (PHP)؟ 1.5 من مترجم إلى مترجم 1.6 ميزات PHP 1.7 ما الذي تحتاجه للعمل؟ 1.8 إجابات لأسئلتك 1.9 خاتمة للفصل 2.1 التثبيت والتكوين 2.2 تثبيت Apache 2.3 تثبيت PHP 2.4 تثبيت MySQL 2.5 تكوين Apache 2.6 تكوين PHP 2.7 تكوين MySQL 2.8 اختبار برامج Apache و PHP 2.9 الخلاصة إلى الفصل الثاني 3.1 تركيب لغة PHP 3.2 إدخال احترافي 3.3 PHP و HTML 3.4 التعليقات في اللغة (الكود) PHP 3.5 تنسيق كود PHP الخاص بالبرنامج 3.6 الخاتمة للفصل 3 4.1 المتغيرات. ما هي المتغيرات؟ 4.2 المتغيرات. أنواع البيانات في PHP 4.3 Integer. نوع البيانات. 4.4 مزدوج. نوع البيانات. 4.5 قيمة منطقية. نوع البيانات. 4.6 أنواع البيانات الأخرى 4.7 تحديد المتغيرات في PHP 4.8 تغيير أنواع البيانات في PHP 4.9 مراجع للمتغيرات في PHP 4.10 المتغيرات الديناميكية في PHP 4.11 ما هي الثوابت في PHP؟ 4.12 تعريف الثوابت في PHP 4.13 الثوابت المحددة مسبقًا في PHP 4.14 الخاتمة للفصل الرابع 5.1 عوامل التشغيل في PHP 5.2 عامل التعيين في PHP 5.3 العمليات الحسابية في PHP 5.4 المعاملات العلائقية في PHP 5.5 المعاملات المنطقية في PHP 5.6 معاملات Bitwise في PHP 5.7 String Operators في PHP 5.8 عامل منع الخطأ في PHP 5.9 عوامل الزيادة والنقصان في PHP 5.10 تدوين الاختزال للتخصيص المتغير في PHP 5.11 الأسبقية والترابط في PHP 5.12 الخاتمة للفصل 5 6.1 عبارات التحكم في PHP 6.2 العبارة الشرطية IF 6.3 عامل Elseif الشرطي 6.4 تبديل المشغل الشرطي 6.5 عوامل الحلقات 6.6 أثناء بيان الحلقة 6.7 ... بينما بيان الحلقة 6.8 بيان الاستراحة غير المشروط 6.9 بيان المتابعة غير المشروط 6.10 بيان الخروج غير المشروط 6.11 يتطلب 6.12 تضمين 6.13 خاتمة للفصل 6 7.1 الوظائف في PHP 7.2 تحديد الوظائف في PHP 7.3 الوسيطات الوظيفية في متغير PHP 7.4 مجال 7.5 عمر المتغيرات في PHP 7.6 Recursion في PHP 7.7 استدعاءات الوظائف الديناميكية في PHP 7.8 الخاتمة للفصل 7 8.1 المصفوفات في PHP 8.2 تعيين قيم لمصفوفات PHP 8.3 Function array () PHP 8.4 إخراج مصفوفات PHP 8.5 العابرة لمصفوفات PHP. وظيفة Count () ، foreach () الإنشاءات 8.6 إعادة تعيين () دالة 8.7 لكل () قائمة 8.8 () 8.9 إضافة المصفوفات 8.10 مقارنة المصفوفات 8.11 إضافة عناصر الصفيف 8.12 حذف عناصر المصفوفة 8.13 فرز المصفوفات 8.14 المصفوفات متعددة الأبعاد 8. 15 التحويل إلى مصفوفة 8.16 الخاتمة إلى الفصل 8 9.1 السلسلة 9.2 معالجة المتغيرات داخل السلاسل 9.3 سلاسل الإخراج 9.4 تنسيق الناتج 9.5 طول السلسلة في PHP 9.6 العثور على سلسلة فرعية في سلسلة 9.7 تنظيف السلاسل 9.8 الخاتمة للفصل 9 10.1 العمل باستخدام نماذج HTML 10.2 تمرير نماذج بيانات HTML. طريقة GET and POST 10.3 استرداد البيانات في مصفوفات PHP 10.4 Superglobal $ _GET و $ _POST 10.5 خاتمة للفصل 10 11.1 فتح الملفات في PHP 11.2 إغلاق الملفات في PHP 11.3 قراءة الملفات وكتابتها في PHP 11.4 نسخ الملفات وحذفها وإعادة تسميتها في PHP 11.5 Retrieving معلومات الملف في PHP 11.6 File Pointer في PHP 11.7 دلائل الفتح والإغلاق في PHP 11.8 قراءة الدلائل في PHP 11.9 إنشاء وحذف الدلائل في PHP 11.10 الخاتمة للفصل 11 12.1 العمل مع قواعد بيانات MySQL في PHP 12.2 توصيل PHP بخادم قاعدة بيانات MySQL 12.3 إنشاء وحذف قاعدة بيانات MySQL 12.4 إنشاء وحذف جداول MySQL 12.5 العمل مع بيانات MySQL 12.6 خاتمة للفصل 12 13.1 العمل مع الصور في PHP. مكتبة GD 13.2 إنشاء وعرض الصور في PHP 13.3 تعديل الصور في PHP 13.4 العمل مع النص في PHP 13.5 خاتمة للفصل 13 14.1 العمل مع التاريخ والوقت في PHP 14.2 تنسيق التاريخ والوقت في PHP 14.3 التاريخ () والتاريخ () الوظيفة في PHP 14.4 التحويلات إلى الوقت المطلق في PHP 14.5 الخاتمة للفصل 14 15.1 العمل مع التعبيرات العادية في PHP 15.2 تعبيرات POSIX العادية في PHP 15.3 الأحرف الأولية في PHP 15.4 فئات الأحرف 15.5 المحددات الكمية 15.6 استبدال أحرف البدل 15.7 أمثلة التعبير العادي 15.8 الخاتمة للفصل 15 16.1 العمل مع ملفات تعريف الارتباط في PHP 16.2 إنشاء ملفات تعريف الارتباط في PHP 16.3 القراءة من ملفات تعريف الارتباط 16.4 حذف ملفات تعريف الارتباط 16.5 الخاتمة للفصل 16

عند شرح حل المشكلات ، غالبًا ما يستخدم علماء الرياضيات عبارة "عن طريق الاستقراء" ، والتي تحير الكثيرين ، لأن هذا المفهوم ليس أبسطها. يوجد أيضًا نوع من الاستقراء في البرمجة يسمى العودية.

على سبيل المثال ، دعنا نحاول كتابة دالة باستخدام حلقة for العادية التي تُرجع معامل الرقم. ومعلوم من مقرر الرياضيات أنها تحسب كالتالي: n! = 1 * 2 ... * (س -1) * ن. علاوة على ذلك ، 0! = 1 ، ولا توجد عوامل سالبة (سرد 7.13).

قائمة 7.13. دالة لإيجاد مضروب رقم بدون العودية.

<لغة البرمجة>
<رئيس>
‹Title ... وظيفة إيجاد مضروب رقم بدون العودية ‹/title ...

<الجسم>
<؟ بي أتش بي
مضروب الوظيفة ($ num)
{
إذا ($ num (
العودة 0 ؛
}
إذا ($ num == 0)
{
العودة 1 ؛
}
لـ ($ i = 1 ، $ sum = 1 ؛ $ i (
$ sum = $ sum * $ i؛
}
إرجاع المبلغ $؛
}

?›


لذا ، تم حل المشكلة ، كما يقولون ، "وجهاً لوجه". إذا تم تمرير القيم السالبة ، سترجع الدالة 0. يتم تنفيذ ذلك باستخدام أول عبارة if. علاوة على ذلك ، إذا تم تمرير الرقم 0 ، فإننا نعيد واحدًا. أخيرًا ، في الحلقة for ، احسب العامل لأي قيمة أخرى.

عند حل المشكلات باستخدام العوديةمطلوب نوع مختلف من التفكير. على سبيل المثال ، يمكن حساب مضروب الرقم على النحو التالي:

ن! = 1 إذا كان n = 0
ن! = n * (n-1)! ، إذا كانت n> 0

لاحظ أن العبارة الثانية تحتوي على علامة عاملة. هذه هي النقطة الرئيسية للتكرار. عند حل مشكلة معينة ، نستخدم ما نحتاج إلى إيجاده. في البرمجة ، تسمى الوظيفة بالعودية إذا كان وصفها يحتوي على مرجع لنفسها.

لذا ، عد إلى الحجة المضروبة. عند حل المشكلات باستخدام العودية ، تحتاج دائمًا إلى نوعين من العبارات: الأساسية والعودية. في حالتنا ، البيان الأساسي هو n! = 1 إذا كان n = 0. كما خمنت بالفعل ، عند العمل باستخدام تعليمة تكرارية ، يتعين علينا الانتقال إلى الجملة الأساسية والحصول على النتيجة. الآن دعونا نحاول وضع كل هذا موضع التنفيذ (قائمة 7.14).

قائمة 7.14. دالة لإيجاد مضروب رقم مع العودية

<لغة البرمجة>
<رئيس>
‹Title ... وظيفة لإيجاد مضروب العدد بالعودية ‹/title ...

<الجسم>
<؟ بي أتش بي
مضروب الوظيفة ($ num)
{
إذا ($ num (
العودة 0 ؛
}
إذا ($ num == 0)
{
العودة 1 ؛
}
إرجاع عدد $ * عاملي ($ num-1) ؛ // إخراج متكرر
}
مضروب الصدى (3) ؛ // سيطبع 6
?›


في هذه الحالة ، يتشابه الشرطان الأولان مع المثال الذي تمت مناقشته أعلاه. لكن الآن ، بدلاً من الحلقة for ، نكتب تعبيرًا تعاوديًا تستدعي فيه الوظيفة نفسها. في برنامجنا ، يحدث هذا حتى الرقم 0 كمعامل إدخال ، حيث ستعيد الوظيفة 1. علاوة على ذلك ، لن تعود هذه القيمة إلى البرنامج الرئيسي ، ولكن إلى جسم الوظيفة السابقة. هذه الوظيفة ، بدورها ، ستعيد قيمتها إلى جسم الوظيفة التالية ، وما إلى ذلك ، حتى يتم إرجاع القيمة المطلوبة إلى البرنامج الرئيسي.

هل يمكن لأي شخص أن يشرح لي دالة تكرارية في PHP (بدون استخدام فيبوناتشي) بلغة الشخص العادي وبأمثلة؟ كنت أبحث عن مثال ، لكن فيبوناتشي فقدني تمامًا!

شكرًا مقدمًا ؛-) أيضًا ، كم مرة تستخدمها في تطوير الويب؟

17 إجابة 17

شروط عامة:

الوظيفة العودية هي وظيفة تستدعيها هي نفسها

المزيد من التفاصيل:

إذا استمرت الوظيفة في استدعاء نفسها ، كيف تعرف متى تتوقف؟ لقد قمت بإنشاء شرط يُعرف باسم الحالة الأساسية. تخبر الحالات الأساسية مكالمتنا المتكررة متى تتوقف ، وإلا فسوف تكرر نفسها إلى أجل غير مسمى.

كان مثالًا تعليميًا جيدًا بالنسبة لي لأنني أجيد الرياضيات

<--calling itself. } }

عندما يتعلق الأمر باستخدام الوظائف العودية في تطوير الويب ، فأنا شخصياً لا ألجأ إلى استخدام المكالمات المتكررة. لا يعني ذلك أنني أعتبر الاعتماد على العودية ممارسة سيئة ، لكن لا ينبغي أن تكون خيارك الأول. يمكن أن تكون قاتلة إذا لم يتم استخدامها بشكل صحيح.

بينما لا يمكنني التنافس مع مثال الدليل ، آمل أن يكون هذا مفيدًا.

(20.04.10) التحديث:

سيكون من المفيد أيضًا التحقق من هذا السؤال ، حيث توضح الإجابة المقبولة ، بعبارات عامة ، كيف تعمل الدالة العودية. على الرغم من أن سؤال OP كان حول Java ، فإن المفهوم هو نفسه ،

23-05-2017 11:33: 24Z

من الأمثلة على ذلك طباعة كل ملف في أي مجلدات فرعية لدليل معين (ما لم يكن لديك روابط رمزية داخل تلك الدلائل التي قد تعطل الوظيفة بطريقة ما). يبدو الرمز الكاذب لطباعة جميع الملفات كما يلي:

الوظيفة printAllFiles ($ dir) (foreach (getAllDirectories ($ dir) مثل $ f) (printAllFiles ($ f) ؛ // هنا هي المكالمة العودية) foreach (getAllFiles ($ dir) مثل $ f) (echo $ f؛) )

الفكرة هي طباعة جميع الدلائل الفرعية أولاً ثم ملفات الدليل الحالي. تنطبق هذه الفكرة على جميع الأدلة الفرعية ، وهذا هو سبب استدعاء هذه الوظيفة بشكل متكرر لجميع الأدلة الفرعية.

إذا كنت ترغب في تجربة هذا المثال ، يجب عليك التحقق من الدلائل الخاصة. و .. ، وإلا فإنك تتعثر في استدعاء printAllFiles (".") طوال الوقت. أيضًا ، يجب عليك التحقق مما تريد طباعته وما هو دليل العمل الحالي الخاص بك (انظر opendir () ، getcwd () ، ...).

2013-11-18 14:16: 52Z

العودية هو ما يعيد نفسه. مثل وظيفة تستدعي نفسها من الداخل. اسمحوا لي أن أوضح بمثال زائف إلى حد ما:

تخيل أن رفاقك يشربون الجعة ، لكن زوجتك ستقتلك إذا لم تصل إلى المنزل قبل منتصف الليل. للقيام بذلك ، دعنا ننشئ أمر وظيفة AndDrinkBeer (بالدولار مرة) ، حيث يكون الوقت بالدولار هو منتصف الليل مطروحًا منه الوقت المستغرق لإنهاء المشروب والعودة إلى المنزل.

لذلك ، عندما تصل إلى البار ، تطلب بيرة لأول مرة وتبدأ في الشرب:

$ timeToGoHome = "23" ؛ // لنمنح أنفسنا ساعة لإجراء المكالمة الأخيرة والحصول على طلب وظيفة المنزل AndDrinkBeer ($ timeToGoHome) (// لنقم بإنشاء الوظيفة التي ستطلق على نفسها. $ Beer = New Beer () ؛ // دعنا " نحصل على بيرة جديدة $ currentTime = date ("G") ؛ // الساعة الحالية بتنسيق 24 ساعة بينما ($ beer-> status! = "blank") (// حان الوقت لبدء حلقة الشرب $ beer- > drink () ؛ // خذ رشفة أو اثنتين من البيرة (أو إذا كان هذا هو ما تفضله)) // الآن نحن خارج حلقة الشرب ومستعدون لبيرة جديدة إذا ($ currentTime< $timeToGoHome) { // BUT only if we got the time orderAndDrinkBeer($timeToGoHome); // So we make the function call itself again! } else { // Aw, snap! It is time:S break; // Let"s go home:(} }

الآن ، دعنا نأمل فقط أنك لم تكن قادرًا على شرب ما يكفي من الجعة للتسمم لدرجة أن زوجتك تجعلك تنام على الأريكة على الرغم من عدم عودتك إلى المنزل في الوقت المحدد.

لكن نعم ، هذا هو بالضبط كيف يحدث العودية.

2010-10-27 10: 59: 35Z

هذه وظيفة تستدعي نفسها. هذا مفيد لاجتياز بنيات بيانات معينة متكررة ، مثل الأشجار. يعد HTML DOM مثالًا كلاسيكيًا.

مثال على بنية شجرة في جافا سكريبت ووظيفة تكرارية "لاجتياز" الشجرة.

1 / \ 2 3 / \ 4 5

Var tree = (id: 1، left: (id: 2، left: null، right: null)، right: (id: 3، left: (id: 4، left: null، right: null)، right: ( المعرف: 5 ، اليسار: null ، اليمين: null))) ؛

لاجتياز الشجرة ، نقوم باستدعاء نفس الوظيفة بشكل متكرر ، حيث نقوم بتمرير أبناء العقدة الحالية إلى نفس الوظيفة. ثم نسمي الوظيفة مرة أخرى ، أولاً على اليسار ثم على اليمين.

في هذا المثال ، سنحصل على أقصى عمق للشجرة

عمق Var = 0 ؛ function walkTree (العقدة ، i) (// قم بزيادة عداد العمق الخاص بنا وتحقق من i ++ ؛ إذا (i> العمق) العمق = i ؛ / / استدعاء هذه الوظيفة مرة أخرى لكل من العقد الفرعية (العودية!) إذا (العقدة. left! = null) walkTree (node.left، i)؛ if (node.left! = null) walkTree (node.right، i)؛ // تقليل عداد العمق الخاص بنا قبل الرجوع إلى مكدس الاستدعاء i-- ؛)

أخيرًا ، نسمي الوظيفة

تنبيه ("عمق الشجرة:" + walkTree (شجرة ، 0)) ؛

طريقة رائعة لفهم العودية هي التنقل خلال التعليمات البرمجية الخاصة بك في وقت التشغيل.

2010-04-15 22:15: 09Z

من السهل جدًا عندما تستدعي دالة ما نفسها لأداء مهمة لعدد غير محدد ومحدود من المرات.

الوظيفة category_tree ($ الأصل = 0 ، $ sep = "") ($ q = "اختر المعرّف ، الاسم من الفئة حيث parent_id =". $ Parent؛ $ rs = mysql_query ($ q) ؛ while ($ rd = mysql_fetch_object ($ rs)) (echo ("id." ">". $ sep. $ rd-> name. "") ؛ category_tree ($ rd-> id ، $ sep. "-") ؛))

2010-10-27 12:44: 20Z

العودية هي طريقة رائعة لقول ، "افعلها مرة أخرى حتى تفعلها".

شيئين مهمين:

  1. الحالة الأساسية. لديك هدف للوصول إليه.
  2. اختبار - كيف تعرف ما إذا كنت قد وصلت إلى حيث أنت ذاهب.

تخيل مهمة بسيطة: قم بفرز مجموعة من الكتب أبجديًا. ستكون العملية البسيطة هي أخذ أول كتابين وفرزهما. الآن هذا هو الجزء التكراري: هل هناك المزيد من الكتب؟ إذا كان الأمر كذلك ، فقم بذلك مرة أخرى. القيام بذلك مرة أخرى هو العودية. "هل هناك المزيد من الكتب" هو اختبار. و "لا ، لم يعد هناك كتب" هي الحالة الأساسية.

2010-04-15 21: 48: 00Z

هذا بسبب شيء واحد:

يتم إنشاء الوظيفة في الذاكرة عند استدعائها (يتم إنشاء مثيل جديد)

لذا فإن الدالة العودية لم يستدع، ولكنها تستدعي حالة أخرى - لذلك لا توجد وظيفة واحدة في الذاكرة تقوم بعمل السحر. إنها بضع حالات في الذاكرة تعيد بعض القيم إلى نفسها - وهذا السلوك هو نفسه ، على سبيل المثال ، عندما تعمل وظيفة استدعاءات ب. لديك مثيلين ، وأيضًا إذا كانت الوظيفة العودية تستدعي مثيلًا جديدًا من نفسها.

حاول رسم الذاكرة في نسخ على الورق - سيكون ذلك منطقيًا.

2017-04-14 05: 17: 49Z

تعد العودية بديلاً عن حلقات for ، فهي نادرًا ما تمنح شفرتك مزيدًا من الوضوح أو الأناقة. تم تقديم مثال جيد من خلال إجابة Progman: إذا لم تستخدم العودية ، فسيتم إجبارها على تتبع الدليل الموجود حاليًا (وهذا ما يسمى الحالة) من العودية ، مما يسمح لها بإجراء مسك الدفاتر باستخدام المكدس (المنطقة التي يتم فيها تخزين المتغيرات وعنوان إرجاع الطريقة)

الأمثلة المعيارية لـ Factial و Fibonacci عديمة الفائدة لفهم المفهوم حيث يمكن استبدالها بسهولة بدورة.

2010-04-15 21:46: 11Z

خاصة. يستمر في الاتصال بنفسه حتى ينتهي

باطل print_folder (جذر سلسلة) (Console.WriteLine (root) ؛ foreach (مجلد var في Directory.GetDirectories (root)) (print_folder (folder) ؛))

يعمل أيضًا مع الحلقات!

الحلقة السابقة الباطلة (int c) (if (c == 0) return؛ print "hi"؛ pretend_loop (c-)؛)

يمكنك أيضًا تجربة البحث في Google عنه. انتبه إلى "هل تقصد" (اضغط عليها ...). http://www.google.com/search؟q=recursion&spell= 1ص>

2015-08-14 09:56: 52Z

إليك مثال عملي (هناك بعض الأمثلة الجيدة بالفعل). أردت فقط إضافة واحد يكون مفيدًا لأي مطور تقريبًا.

في مرحلة ما ، سيحتاج المطورون إلى تحليل الكائن ، كما هو الحال في استجابة API أو نوع من الكائن أو المصفوفة.

يتم استدعاء هذه الوظيفة مبدئيًا لتحليل كائن يمكن أن يحتوي فقط على معلمات ، ولكن ماذا لو كان الكائن يحتوي أيضًا على كائنات أو مصفوفات أخرى؟ سيحتاج هذا إلى حل ، وبالنسبة للجزء الأكبر ، فإن الوظيفة الرئيسية تقوم بذلك بالفعل ، لذا فإن الوظيفة تستدعي نفسها مرة أخرى (بعد التأكد من أن المفتاح أو القيمة هي كائن أو مصفوفة) وتوزع ذلك الكائن أو المصفوفة الجديدة. في النهاية ، يتم إرجاع سلسلة تنشئ كل معلمة على السلسلة بشكل منفصل لسهولة القراءة ، ولكن يمكنك أيضًا كتابة القيم بسهولة إلى ملف سجل أو إدراجها في قاعدة بيانات أو أي شيء آخر.

أضفت معامل البادئة $ لاستخدام الأصل لوصف المتغير النهائي حتى نتمكن من رؤية ما تشير إليه القيمة. لا يتضمن أشياء مثل القيم الفارغة ، ولكن يمكن تغيير ذلك من هذا المثال.

إذا كان لديك كائن:

$ apiReturn = new stdClass () ؛ $ apiReturn-> shippingInfo = new stdClass () ؛ $ apiReturn-> shippingInfo-> fName = "Bill" ؛ $ apiReturn-> shippingInfo-> lName = "اختبار" ؛ $ apiReturn-> shippingInfo-> address1 = "22 S. Deleware St."؛ $ apiReturn-> shippingInfo-> city = "Chandler" ؛ $ apiReturn-> shippingInfo-> state = "AZ" ؛ $ apiReturn-> shippingInfo-> zip = 85225 ؛ $ apiReturn-> phone = "602-312-4455" ؛ $ apiReturn-> transactionDetails = array ("totalAmt" => "100.00"، "currency" => "USD"، "tax" => "5.00"، "shipping" => "5.00") ؛ $ apiReturn-> item = new stdClass ()؛ $ apiReturn-> item-> name = "T-shirt" ؛ $ apiReturn-> item-> color = "blue" ؛ $ apiReturn-> item-> itemQty = 1 ؛

واستخدم:

Var_dump ($ apiReturn) ؛

سيعود:

الكائن (stdClass) # 1 (4) (["shippingInfo"] => كائن (stdClass) # 2 (6) (["fName"] => سلسلة (4) "Bill" ["lName"] => سلسلة ( 4) "Test" ["address1"] => Line (18) "22 S. Deleware St." ["City"] = سلسلة (8) "Chandler" ["state"] => سلسلة (2) "AZ "[" zip "] => int (85225)) [" phone "] => سلسلة (12)" 602-312-4455 "[" actionDetails "] => array (4) ([" totalAmt "] => string (6) "100.00" ["currency"] => سلسلة (3) "USD" ["tax"] => سلسلة (4) "5.00" ["shipping"] => سلسلة (4) "5.00") ["item"] => كائن (stdClass) # 3 (3) (["name"] => سلسلة (7) "T-shirt" ["color"] => سلسلة (4) "blue" ["itemQty "] => int (1)))

وإليك الكود لتحليلها في سطر مع فاصل أسطر لكل معلمة:

دالة parseObj ($ obj، $ prefix = "") ($ stringRtrn = ""؛ foreach ($ obj as $ key => $ value) (if ($ prefix) (switch ($ key) (case is_array ($ key) : foreach ($ key as $ k => $ v) ($ stringRtrn. = parseObj ($ key، $ obj)؛) break؛ case is_object ($ key): $ stringRtrn. = parseObj ($ key، $ obj)؛ break ؛ افتراضي: التبديل (القيمة $) (الحالة is_array (القيمة $): $ stringRtrn. = parseObj ($ value، $ key)؛ break؛ case is_object ($ value): $ stringRtrn. = parseObj ($ value، $ key ) ؛ كسر ؛ افتراضي: $ stringRtrn. = $ بادئة. "_". $ key. "=". $ value. "
"؛ break؛) break؛)) else (// end if ($ prefix) switch ($ key) (case is_array ($ key): $ stringRtrn. = parseObj ($ key، $ obj)؛ break؛ case is_object ( $ key): $ stringRtrn. = parseObj ($ key، $ obj)؛ break؛ افتراضي: switch ($ value) (الحالة is_array ($ value): $ stringRtrn. = parseObj ($ value، $ key)؛ break؛ case is_object (القيمة $): $ stringRtrn. = parseObj ($ value، $ key)؛ break؛ الافتراضي: $ stringRtrn. = $ key. "=". $ value. "
"؛ break؛) // end الداخلي switch) // end External switch) // end else) // end foreach ($ obj مثل $ key => $ value) تُرجع $ stringRtrn؛) // END parseObj ()

سيؤدي هذا إلى إرجاع كائن مثل هذا:

ShippingInfo_fName = فاتورة shippingInfo_lName = اختبار shippingInfo_address1 = 22 S. Deleware St. shippingInfo_city = Chandler shippingInfo_state = AZ shippingInfo_zip = 85225 phone = 602-312-4455 transactionDetails_totalAmt = 100.00 transactionDetails_currency = USD transactionDetails_tax = 5.00 transactionDetails_shipping = 5.00 item_name = T-shirt item_ty blue 1 item_item =

لقد صنعت المشغلين مفتاح متداخللتجنب الالتباس مع if. ... ... لو غير هذا. ... ... آخر ، لكنها كانت تقريبًا بنفس الطول. إذا كان ذلك مفيدًا ، فما عليك سوى طلب عبارات if ويمكنني إدخالها لمن يحتاجون إليها.

2017-01-15 20:40: 28Z

المشي في شجرة الدليل هو مثال جيد. يمكنك القيام بشيء مثل هذا لمعالجة المصفوفة. هذه وظيفة عودية بسيطة حقًا تعالج ببساطة سلسلة أو مصفوفة بسيطة من السلاسل أو مجموعة متداخلة من السلاسل بأي عمق ، وتستبدل مثيلات "hello" بـ "goodbye" في السلسلة أو قيم صفيف أو أي مصفوفة متداخلة أخرى:

الوظيفة replaceHello ($ a) (if (! Is_array ($ a)) ($ a = str_replace ("hello"، "goodbye"، $ a)؛) else (foreach ($ a as $ key => $ value) ( $ a [$ key] = replaceHello ($ value)؛)) إرجاع $ a)

إنه يعرف متى يخرج لأن الشيء الذي يقوم بمعالجته في وقت ما ليس مصفوفة. على سبيل المثال ، إذا اتصلت بـ replaceHello ("مرحبًا") ، فسيتم إرجاع "وداعًا". إذا أرسلت لها مصفوفة من السلاسل ، على الرغم من أنها ستستدعي نفسها مرة واحدة لكل عضو في المصفوفة ، ثم تعيد المصفوفة المعالجة.

2014-07-04 22:16:16Z

إذا أضفت قيمة محددة (قل "1") إلى مثال أنتوني فورلوني ، فسيكون كل شيء واضحًا:

حقيقة الوظيفة (1) (if (1 === 0) (// الحالة الأساسية الخاصة بنا تُرجع 1 ؛) else (إرجاع 1 * حقيقة (1-1) ؛ //<--calling itself. } }

أصلي:

حقيقة الوظيفة ($ n) (if ($ n === 0) (// الحالة الأساسية تُرجع 1 ؛) else (تُرجع $ n * fact ($ n-1) ؛ //<--calling itself. } }

2014-07-21 06: 49: 29Z

هذا مثال بسيط جدًا على مضروب باستخدام العودية:

العوامل هي مفهوم رياضي بسيط للغاية. تمت كتابتها على أنها 5! وهو ما يعني 5 * 4 * 3 * 2 * 1. إذن 6! إنها 720 و 4! إنها 24.

مضروب الوظيفة ($ number) (if ($ number< 2) { return 1; } else { return ($number * factorial($number-1)); } }

أتمنى أن يكون هذا مفيدًا لك. :)

2015-09-15 07: 49: 11Z

العودية المستخدمة في ثابت كابريكار

الدالة KaprekarsConstant ($ num، $ count = 1) ($ input = str_split ($ num) ؛ sort ($ input) ؛ $ ascendingInput = داخليًا ($ input) ؛ $ descendingInput = تنفجر (array_reverse ($ input)) ؛ نتيجة $ = $ ascendingInput> $ descendingInput؟ $ ascendingInput - $ descendingInput: $ descendingInput - $ ascendingInput ؛ إذا ($ result! = 6174) (إرجاع KaprekarsConstant (sprintf ("٪ 04d"، $ result)، $ count + 1)؛) عودة العد $؛

تستمر الوظيفة في استدعاء نفسها بنتيجة الحساب حتى تصل إلى ثابت Kaprekars ، حيث ستعيد عدد المرات التي تم فيها إجراء الحساب.

/ تحرير بالنسبة لأولئك الذين لا يعرفون ثابت كابريكار ، يلزم 4 أرقام برقمين مختلفين على الأقل.

2018-03-02 07: 34: 31Z

لا أجد الأمثلة مفيدة أيضًا. لا يمكنك حل مشكلتين في نفس الوقت ، فعند استخدام الرياضيات ، ينتقل عقلك بين المشكلتين. توقف عن الكلام

مثال: p>

لدي وظيفة حيث أقوم بتقسيم السلاسل إلى مصفوفة بناءً على: المحدد.

الوظيفة العامة explodeString ($ string) (إرجاع explode (":"، $ string)؛)

لدي وظيفة أخرى حيث آخذ السلاسل كمدخلات

الوظيفة العامة doRec () ($ strings = ["no: go"، "hello: world"، "nested" => ["iam: good"، "bad: array"، "bad: how"، "bad: about "،]]؛ $ response =؛ foreach (سلاسل $ كسلسلة $) (array_push ($ response، $ this-> explodeString ($ string))؛) إرجاع $ response؛)

المشكلة هي أن الإدخال الخاص بي يحتوي على مصفوفة متداخلة وأن وظيفة explodeString الخاصة بي تحصل على سلسلة نصية. يمكنني إعادة كتابة بعض التعليمات البرمجية في وظيفة explodeString لاستيعاب ذلك ، لكن ما زلت بحاجة إلى نفس الوظيفة للقيام بنفس العملية على السلسلة الخاصة بي. هذا هو المكان الذي يمكنني فيه استدعاء الطريقة المتكررة في. إذن ها هي الوظيفة الأخيرة explodeString مع العودية.

الوظيفة العامة explodeString ($ string) (if (is_array ($ string)) ($ Combined =؛ foreach ($ string as $ str) (array_push ($ comb، $ this-> explodeString ($ str))؛) إرجاع $ الجمع ؛) عودة تنفجر (":"، $ سلسلة)؛)