פונקציה רקורסיבית: ספירה לאחור
חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-Dart של Coddy. שיעור 48 מתוך 65.
עכשיו הגיע הזמן ליישם רקורסיה בפועל באמצעות פונקציית ספירה לאחור פשוטה. התרגיל הזה יעזור לך להבין כיצד מקרה הבסיס והשלב הרקורסיבי פועלים יחד בקוד אמיתי.
פונקציית ספירה לאחור מתחילה ממספר ומדפיסה את המספרים עד אפס. כך רקורסיה מאפשרת זאת: אם המספר גדול מאפס, מדפיסים אותו ואז קוראים לאותה פונקציה עם מספר קטן יותר. כשהמספר מגיע לאפס, עוצרים.
void countdown(int number) {
if (number <= 0) {
print("Done!");
return; // מקרה בסיס - עוצרים כאן
}
print(number);
countdown(number - 1); // שלב רקורסיבי
}מקרה הבסיס בודק אם number <= 0 — זהו השלב שבו מפסיקים לקרוא לפונקציה. הצעד הרקורסיבי קורא ל־countdown(number - 1), שזו אותה בעיה אך עם קלט קטן יותר, וכך מקרב אותנו בהדרגה אל מקרה הבסיס.
כשקוראים ל־countdown(3), הוא מדפיס 3, ואז קורא ל־countdown(2), שמדפיס 2, ואז קורא ל־countdown(1), שמדפיס 1, ואז קורא ל־countdown(0), שמדפיס "Done!" ועוצר.
אתגר
קלצרו תוכנית שמממשת טיימר ספירה לאחור רקורסיבי עם הודעות מותאמות אישית. התוכנית שלכם תדגים רקורסיה באמצעות ספירה לאחור ממספר נתון והצגת הודעות אישיות בכל שלב.
- קראו קלט מסוג מחרוזת המייצג את המספר ההתחלתי לספירה לאחור
- קראו קלט מסוג מחרוזת המייצג קידומת מותאמת אישית להודעה (לדוגמה,
"Launch in","Timer"או"Countdown") - המירו את הקלט הראשון למספר שלם באמצעות
int.parse() - צרו פונקציה רקורסיבית בשם
customCountdownשמקבלת שני פרמטרים: - מספר שלם
numberהמייצג את ערך הספירה לאחור הנוכחי - מחרוזת
messagePrefixעבור ההודעה המותאמת אישית - הפונקציה צריכה לממש את הלוגיקה הבאה:
- מקרה בסיס: אם המספר קטן מ־0 או שווה לו, הדפיסו
"Countdown complete!"וחזרו - שלב רקורסיבי: הדפיסו את קידומת ההודעה ואחריה את המספר הנוכחי, ואז קראו לפונקציה שוב עם
number - 1 - קראו לפונקציה
customCountdownעם המספר שהומר ועם קידומת ההודעה - הציגו את התוצאות בדיוק בפורמט שמוצג למטה
לדוגמה, אם הקלטים הם "5" ו־"Launch in", התוכנית שלכם צריכה להציג:
Starting countdown from: 5
Message prefix: Launch in
========================
Launch in 5
Launch in 4
Launch in 3
Launch in 2
Launch in 1
Countdown complete!אם הקלטים הם "3" ו־"Timer", התוכנית שלכם צריכה להציג:
Starting countdown from: 3
Message prefix: Timer
========================
Timer 3
Timer 2
Timer 1
Countdown complete!אם הקלטים הם "0" ו־"Ready", התוכנית שלכם צריכה להציג:
Starting countdown from: 0
Message prefix: Ready
========================
Countdown complete!התוכנית שלכם חייבת לממש את הפונקציה הרקורסיבית customCountdown, שקוראת לעצמה עם מספר שהופחת עד שהוא מגיע למקרה הבסיס. הפונקציה צריכה להדפיס את ההודעה המותאמת אישית עם המספר הנוכחי בכל קריאה רקורסיבית, וכך להדגים כיצד רקורסיה מפרקת את הבעיה לתת־בעיות זהות וקטנות יותר. השתמשו באינטרפולציה של מחרוזת כדי לעצב את הודעות הספירה לאחור כך: "$messagePrefix $number".
נסו בעצמכם
import 'dart:io';
// TODO: צרו כאן את הפונקציה customCountdown שלכם
// זכרו לטפל במקרה הבסיס (number <= 0) ובשלב הרקורסיבי
void main() {
// קראו את הקלט
String? startingNumber = stdin.readLineSync();
String? messagePrefix = stdin.readLineSync();
// המירו מחרוזת למספר שלם
int number = int.parse(startingNumber!);
// הציגו את המידע הראשוני
print('Starting countdown from: $number');
print('Message prefix: $messagePrefix');
print('========================');
// TODO: קראו כאן לפונקציה customCountdown שלכם
// זכרו לטפל בבטיחות null עבור messagePrefix
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת התוכנית
1מניפולציות מתקדמות ברשימות
מאפייני רשימה: ראשון ואחרוןמצב הרשימה: isEmpty ו-isNotEmpהיפוך רשימההוספה לרשימה: insertהסרת פריטים מרשימה: removeWhereחיפוש ברשימה: indexOfמיון רשימהערבוב רשימהסיכום – מארגן רשימות4מניפולציה מתקדמת של Map
מעבר על Mapבדיקה אם מפתחות וערכים קיימיםמאפייני Map: מפתחות וערכיםהוספה מותנית: putIfAbsentהסרת רשומות מ־MapMaps מקונניםסיכום – עדכון מלאי7פונקציות מתקדמות
פונקציות אנונימיותהעברת פונקציות כארגומנטיםהבנת סגירותמבוא לרקורסיהפונקציה רקורסיבית: ספירה לאחורפונקציה רקורסיבית: עצרתחזרה: מעבד רשימות2פעולות פונקציונליות על רשימות
טרנספורמציה באמצעות 'map'סינון באמצעות 'where'שימוש ב-'.toList()'בדיקת תנאים באמצעות 'any'תנאים באמצעות 'every'איתור באמצעות 'firstWhere'סיכום – סינון נתונים5פרויקט: חישוב עגלת קניות
הגדרת הפרויקטהוספת פריטים לעגלה3קבוצות
מהי קבוצה?יצירת קבוצההוספה והסרה מקבוצותבדיקת נוכחות של איברים בקבוצההמרת רשימה לקבוצהאיחוד קבוצותחיתוך קבוצותהפרש קבוצותסיכום – רשימת אורחים ייחודית6טיפול בסיסי בשגיאות
מהן חריגות?בלוק ה-try-catchתפיסת חריגות באמצעות onבלוק ה-finallyהשלכת חריגהסיכום – חלוקה בטוחה9טיפוסי מנייה (Enums)
מה הם Enums?הגדרת Enum פשוטשימוש ב-Enums במשתניםEnums במשפטי 'switch'סיכום – רמזורתרגלו בעצמכם: קומפיילר Dart אונליין