פונקציה רקורסיבית: עצרת
חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-Dart של Coddy. שיעור 49 מתוך 65.
עצרת של מספר היא פעולה מתמטית קלאסית שמתאימה במיוחד להדגמת רקורסיה. העצרת של מספר שלם חיובי n (הנכתבת n!) היא המכפלה של כל המספרים השלמים החיוביים מ־1 עד n. לדוגמה, 5! = 5 × 4 × 3 × 2 × 1 = 120.
מה שהופך את העצרת לאידיאלית לרקורסיה הוא שהיא מתפרקת באופן טבעי לבעיות קטנות יותר וזהות. כדי לחשב את 5!, אפשר לחשוב על כך בתור 5 × 4!. ו־4! הוא פשוט 4 × 3!, וכן הלאה. הדפוס הזה נמשך עד שמגיעים ל־1!, ששווה ל־1.
int factorial(int n) {
if (n <= 1) {
return 1; // תנאי בסיס
}
return n * factorial(n - 1); // צעד רקורסיבי
}מקרה הבסיס עוצר את הרקורסיה כאשר n <= 1, ומחזיר 1. הצעד הרקורסיבי מכפיל את המספר הנוכחי בעצרת של המספר הבא הקטן ממנו. כשקוראים ל־factorial(5), היא מחזירה 5 * factorial(4), שמחזירה 5 * 4 * factorial(3), וכן הלאה עד שמגיעים למקרה הבסיס.
הגישה הזו מדגימה כיצד רקורסיה פותרת בעיות באלגנטיות על ידי צמצומן לגרסאות פשוטות יותר של אותה הבעיה, וכך חישובים מורכבים מרגישים טבעיים ואינטואיטיביים.
אתגר
קלצרו תוכנית שמחשבת עצרות עבור כמה מספרים באמצעות רקורסיה. התוכנית תדגים את פונקציית העצרת הרקורסיבית על ידי עיבוד רשימת מספרים וחישוב העצרת של כל אחד מהם.
- קראו מחרוזת קלט שמכילה מספרים המופרדים בפסיקים (למשל,
"3,5,0,7") - פצלו את מחרוזת הקלט למספרים בודדים והמירו כל אחד מהם למספר שלם
- צרו פונקציה רקורסיבית בשם
factorialשמקבלת פרמטר של מספר שלםn - הפונקציה
factorialצריכה לממש את הלוגיקה הבאה: - מקרה בסיס: אם
nקטן מ-1 או שווה לו, החזירו 1 - שלב רקורסיבי: החזירו את
nכפולfactorial(n - 1) - עבור כל מספר ברשימת הקלט, חשבו את העצרת שלו באמצעות הפונקציה הרקורסיבית שלכם
- הציגו את התוצאות, כולל כל מספר ואת העצרת המתאימה לו
- חשבו והציגו את הסכום של כל תוצאות העצרת
לדוגמה, אם הקלט הוא "4,3,2", התוכנית שלכם אמורה להפיק את הפלט הבא:
Factorial Calculator
====================
Processing numbers: [4, 3, 2]
====================
Factorial Results:
4! = 24
3! = 6
2! = 2
====================
Sum of all factorials: 32
Calculation completed successfullyאם הקלט הוא "5,0,1", התוכנית שלכם אמורה להפיק את הפלט הבא:
Factorial Calculator
====================
Processing numbers: [5, 0, 1]
====================
Factorial Results:
5! = 120
0! = 1
1! = 1
====================
Sum of all factorials: 122
Calculation completed successfullyאם הקלט הוא "6", התוכנית שלכם אמורה להפיק את הפלט הבא:
Factorial Calculator
====================
Processing numbers: [6]
====================
Factorial Results:
6! = 720
====================
Sum of all factorials: 720
Calculation completed successfullyהתוכנית שלכם חייבת לממש את הפונקציה הרקורסיבית factorial, שקוראת לעצמה עם ערכים קטנים יותר עד שהיא מגיעה למקרה הבסיס. הפונקציה צריכה להדגים כיצד רקורסיה מפרקת את חישוב העצרת לתת-בעיות קטנות וזהות. השתמשו באינטרפולציה של מחרוזות כדי לעצב את תוצאות העצרת כך: "$n! = $result". זכרו ש-0! שווה ל-1 לפי ההגדרה המתמטית, ומקרה הבסיס שלכם צריך לטפל בכך כראוי.
נסו בעצמכם
import 'dart:io';
// TODO: צרו כאן את הפונקציה הרקורסיבית שלכם לחישוב עצרת
void main() {
// קראו מחרוזת קלט המכילה מספרים המופרדים בפסיקים
String? input = stdin.readLineSync();
// פצלו את הקלט והמירו אותו למספרים שלמים
List<int> numbers = input!.split(',').map((str) => int.parse(str.trim())).toList();
// TODO: כתבו את הקוד שלכם למטה כדי:
// 1. לעבד כל מספר באמצעות הפונקציה שלכם לחישוב עצרת
// 2. לחשב את סכום כל העצרות
// 3. להציג את התוצאות בפורמט הנדרש
print("Factorial Calculator");
print("====================");
print("Processing numbers: $numbers");
print("====================");
print("Factorial Results:");
// TODO: חשבו והציגו כאן את תוצאות חישוב העצרות
print("====================");
// TODO: הציגו את סכום כל העצרות
print("Calculation completed successfully");
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת התוכנית
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 אונליין