C Programming chapter 12
Transcript of C Programming chapter 12
Shayke Bilu PhD SCE-Chapter-12-Recrusion
12פרק
Recursion -רקורסיה
בילור שייקה "ד
יועץ ומרצה בכיר למדעי המחשב וטכנולוגית מידע
אקדמיות ומנהליות, מומחה למערכות מידע חינוכיות
Cקורס יסודות התכנות בשפת
1
מצביעים ומערכים: תזכורת
הגדרת מערך מקצה בזיכרון מקומות רצופים עבור התאים שלו.
שמכיל את , המערך-מוקצה משתנה ששמו הוא שם, בנוסף
(. לא ניתן לשנות את ערכו)כתובת התא הראשון של המערך
י חישוב הכתובת שלהם"לכן אפשר לגשת לתאי מערך גם ע .
.array[5] -לשקול (array+5)*למשל
המחשב יודע לאיזה כתובת לגשת כשעושים את החשבון הזה ,
.כי הוא יודע כמה מקום תופס כל תא במערך לפי סוג ערכים
Shayke Bilu PhD SCE-Chapter-12-Recrusion
array[0] array[9]
. . . . . . . . . . 500
array
(למשל) 500כתובת
2
Shayke Bilu PhD
3
דוגמא נוספת –גישה למערך לפי כתובת
האפשרויות הבאות עושות בדיוק אותו דבר 3, עבור הדפסת מערך:
int i,arr[10]={12,36,45,78,95,42,64,31,75,19};
int *ptr;
for (i=0; i<10; i++)
printf(“%d”, arr[i]);
for (i=0; i<10; i++)
printf(“%d”, *(arr+i));
for (ptr=arr; ptr <= &arr[9]; ptr++)
printf(“%d”, *ptr);
י קידום מצביע מכתובת התא הראשון עד כתובת התא האחרון"הדפסה ע•
ידי גישה רגילה לתאי המערך-הדפסה על•
ידי גישה לכל תא לפי הכתובת שלו -הדפסה על•
יחסית לתא הראשון
SCE-Chapter-12-Recrusion
4
דוגמא נוספת –גישה למערך לפי כתובת
האפשרויות הבאות עושות בדיוק אותו דבר 3, עבור הדפסת מערך:
int i;
char *ptr, arr[12]=“Shalom Taly”;
for (i=0; i<12; i++)
printf(“%c”, arr[i]);
for (i=0; i<12; i++)
printf(“%c”, *(arr+i));
for (ptr=arr; ptr <= &arr[11]; ptr++)
printf(“%c”, *ptr);
י קידום מצביע מכתובת התא הראשון עד כתובת התא האחרון"הדפסה ע•
ידי גישה רגילה לתאי המערך-הדפסה על•
ידי גישה לכל תא לפי הכתובת שלו -הדפסה על•
יחסית לתא הראשון
Shayke Bilu PhD SCE-Chapter-12-Recrusion
הסבר -מערכים ופונקציות
השינויים , כפי שהוסבר בעבר כאשר מעבירים מערך לפונקציה . שנעשה בפונקציה ישפיעו על המערך המקורי
זה נובע מכך שלפונקציה מועברת הכתובת בזיכרון של המערך (.ולא על העתק שלהם)והיא פועלת ישירות על ערכיו , המקורי
הפונקציה הבאה תאפס מערך שמועבר , כפי שאמרנו, למשל :אליה
void zero_array(int arr[ ], int size)
{
int i;
for(i=0 ; i<size; i++)
arr[i]=0;
}
5
SCE-Chapter-12-Recrusion
5
Shayke Bilu PhD
אמרנו בעבר שכשמעבירים מערך לפונקציה שינויים שנעשה . בפונקציה ישפיעו על המערך המקורי
זה נובע מכך שלפונקציה מועברת הכתובת בזיכרון של המערך (.ולא על העתק שלהם)והיא פועלת ישירות על ערכיו , המקורי
הפונקציה הבאה תאפס מערך מועבר, כפי שאמרנו:
void zero_array(int *arr, int size)
{
int i;
for(i=0 ; i<size; i++)
arr[i]=0;
}
6
נציין שאם פונקציה מצפה לקבל
אפשר להעביר אליה מערך , מצביע
כי בשני המקרים מה , מהסוג הזה
.שמועבר הוא כתובת בזיכרון
SCE-Chapter-12-Recrusion
הסבר -מערכים ופונקציות 6
Shayke Bilu PhD
SCE-Chapter-12-Recrusion
על הפועלות שהוזכרו המחרוזתיות הפונקציות למשל
תמיד למעשה מוגדרות (strcmp, strlen כמו) מחרוזות
.* char מטיפוס מצביעים עבור ורק ואך
רצף כלומר) מחרוזת על באמת אותן להפעיל באחריותנו
נקבל) לתו מצביע על סתם ולא ('\0' -ב שמסתיים תווים
.(הסיום תו את אין אם שגויות תוצאות
7
הסבר -מערכים ופונקציות 7
Shayke Bilu PhD
SCE-Chapter-12-Recrusion
בגודל מערך על מוגדרת פונקציה אם ,כזכור ,כן-כמו
של אחר בגודל מערך גם אליה להעביר ניתן ,מסוים
כתובת רק זה שמועבר מה כאמור כי) טיפוס אותו
.(ההתחלה
הגיונית פעולה בפונקציה שתתבצע באחריותנו זה ,שוב
.ממנו תחרוג ולא המערך גודל מה תדע ושהיא
8
הסבר -מערכים ופונקציות 8
Shayke Bilu PhD
Shayke Bilu PhD SCE-Chapter-12-Recrusion
נקודה לתשומת לב –מערכים ופונקציות
אם ננסה להחזיר מפונקציה מערך שהגדרנו בתוכה או
.אז נקבל שגיאה, מצביע על מערך כזה
int * zero_array()
{
int array[100]={0};
return array;
}
אבל כל מה , זה מכיוון שמוחזרת כתובת של המערך
.שהוגדר בתוך הפונקציה נמחק כשהיא מסתיימת
9 9
הגדרת מבנה חדש -מבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
ידי שתי קואורדינטות-נקודה במישור מיוצגת על ,X ו- Y .
הגדרת מבנה שייצג נקודה תיראה למשל כך:
struct point
{
double x;
double y;
};
כ "בד)אלא בתחילת הקובץ , ההגדרה הזו לא תופיע בתוך פונקציה
(.define# -וה include# -מיד אחרי שורות ה
כפי שנבחן , כעת ניתן להגדיר בתוכנית משתנים מהסוג הזה
. בהמשך
11
Shayke Bilu PhD SCE-Chapter-12-Recrusion
ממנו/לקרוא אליו/ניתן לגשת לכל אחד משדות המבנה ולכתוב ,
:למשל
int main()
{
struct point P1,P2;
P1.x = 6.5;
P1.y = 7.2;
P2.x = 4.6;
P2.y = 2.9;
printf(“%.2lf\n”, P1.y);
return 0;
}
P1 P2
4.6
7.2 2.9
6.5 x
y
x
y
(7.2יודפס )
הגדרת מבנה חדש -מבנים -חזרה 12
Shayke Bilu PhD SCE-Chapter-12-Recrusion
#include <stdio.h> struct point { double x; double y; }; int main() { struct point P1,P2; P1.x = 6.5; P1.y = 7.2; P2.x = 4.6; P2.y = 2.9; printf(“%.2lf,%.2lf\n”,P1.x,P1.y); return 0; }
P1 P2
4.6
7.2 2.9
6.5 x
y
x
y
הגדרת מבנה חדש -מבנים -חזרה 13
כתיבה מקוצרת –מבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
שמו של הטיפוס החדש שהגדרנו הואstruct point
אפשר לחסוך את כתיבת המילהstruct באמצעות הפקודה
typedef ,משתנה-שמאפשרת לתת שם חדש לטיפוס :
struct point
{
double x;
double y;
};
typedef struct point point_t;
טיפוס קיים שם חדש
14
typedefעוד על -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
struct complex
{
double real, image;
}; int main()
{
struct complex c={5,7};
struct complex *pc;
pc=&c;
}
struct complex
{
double real, image;
};
typedef struct complex
complex_t;
int main()
{
complex_t c={5,7};
complex_t *pc;
c=&pc;
}
15
מצביעים ומבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
כדי להגיע לשדות של , בדוגמא זוP דרךptr שמצביע
:כרגיל * -אפשר להשתמש ב, Pעל
(*ptr).x = 3; שקול ל- P.x = 3;
(*ptr).y = 7; שקול ל- P.y = 7;
כי אחרת לנקודה יש קדימות על פני יש צורך בסוגריים
.* -ה
16
גישה לשדות המבנה –מצביעים ומבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
כדי להגיע לשדות של , בדוגמא זוP דרךptr שמצביע עלP ,
:כרגיל* -אפשר להשתמש ב
(*ptr).x = 5; שקול ל- P.x = 5;
(*ptr).y = 8; שקול ל- P.y = 8;
חץ : כלל נשתמש לצורך זה בסימון מקוצר-אבל בדרך->
ptr -> x = 5; שקול ל- P.x = 5;
ptr -> y = 8; שקול ל- P.y = 8;
כלומר משמעות החץ היא גישה לשדה במבנה שמצביעים עליו.
17
Shayke Bilu PhD SCE-Chapter-12-Recrusion
struct complex
{
double real;
double image;
};
int main()
{
struct complex c;
c.real = 5;
c.image = 7;
}
5
7 c.image:
c.real:
c
במצביעיםשימוש - Syntax מבנים -חזרה 18
Shayke Bilu PhD SCE-Chapter-12-Recrusion
5
7 c.image:
c.real:
c typedef struct {
double real, image;
}comples;
int main()
{
complex c;
complex *pc;
c.real = 5; c.image = 7;
pc = &c;
pc->real = 3;
pc->image = 4;
}
pc 0x7fff9255c05c 3
4 pc.image:
pc.real:
pc
ומצביעיםכתובות - Syntax מבנים -חזרה 19
0x7fff9255c05c
0x7fff9255c05c
מבנה בתוך מבנה -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
ידי הקואורדינטות של שני -אפשר להגדיר את זה על :הקודקודיים
struct rect { double xl, xh, yl, yh; };
נקודות 2י "עברור יותר להגדיר. כאן גם את הרישום המקוצר עם נדגיםtypedef:
struct rect { point_t p; point_t q; }; typedef struct rect rect_t;
20
כתיבה מקוצרת –מבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
שמו של הטיפוס החדש שהגדרנו היהstruct point
אפשר לחסוך את כתיבת המילהstruct באמצעות הפקודהtypedef ,משתנה-שמאפשרת לתת שם חדש לטיפוס :
typedef struct
{
double x;
double y;
} point;
21
double x
double y
point
מערך של מבנים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
אפשר להגדיר מערך של מבנים, כמו טיפוסי משתנים אחרים.
מערך זה יוגדר ויכיל בתוכו שדות שהם מבנים הכוללים תתי
.שדות
אפשר להגדיר מערך של נקודות, למשל:
int main()
{
point arr[20];
…
…
return 0;
}
22
מערך של מלבנים בזיכרון -חזרה
rect_t
rect_t
rect_t
rect_t
rect_t
rect_t
rect_t
point p
point q
double x
double y
double x
double y
Shayke Bilu PhD SCE-Chapter-12-Recrusion
כל מלבן מכיל שני
מטיפוסשדות
point
כל נקודה מכילה שני
מטיפוס שדות
double
:בזיכרוןהמלבנים נשמרים ברצף
23
ומבניםמערכים -חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
שכמו מאחר ומבנים מגדירים סוג חדש של משתנים הרי • .סוגים אלומערכים עבור ניתן ליצור לסוגים רגילים
5
7
2
1
7
2
1
8
complex_t arr[SIZE]=
{{5,7},{2,1},{7,2},{1,8}}
arr[1].real = 2;
arr[1].image = 9;
arr[3].real = 3;
arr[3].image = 8;
array
real:
image: 0
1
2
3
24
real:
image:
real:
image:
real:
image:
מערכים ומבנים אחרי ביצוע הפקודות- חזרה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
5
7
9
2
7
2
8
3
array
0
1
2
3
complex_t arr[SIZE]=
{{5,7},{2,1},{7,2},{1,8}}
arr[1].real = 9;
arr[1].image = 2;
arr[3].real = 8;
arr[3].image = 3;
25
real:
image:
real:
image:
real:
image:
real:
image:
Shayke Bilu PhD SCE-Chapter-12-Recrusion
27
רקורסיה
שלה מופע שכל תופעה היא (נסיגה :בעברית) רקורסיה•
ומשתקפת מתרחשת שהיא כך ,שלה נוסף מופע מכיל
.ושוב שוב עצמה בתוך בשלמותה
רקורסיית או) עצירה רקורסיית להיות יכולה רקורסיה•
לא שמתחתיה רמה – "עצירה סף" בה יש כאשר ,(קצה
כאשר אינסופית רקורסיה או ,הרקורסיה עוד מתקיימת
.סוג מאותו משנה תופעות התופעה תכיל רמה בכל
27
Shayke Bilu PhD SCE-Chapter-12-Recrusion
28
רקורסיה
כאשר ,יותר או תופעות שתי בין מתרחשת הדדית רקורסיה•
',ב של מופע מכיל 'א :חלילה וחוזר השנייה את מכילה האחת
מקיימים הם – כאחד 'וב 'א על נביט אם) 'א של מופע מכיל 'וב
.מראה מול מראה מוצבת כאשר למשל ,(רגילה רקורסיה
בעיה לפתור מנת על אשר אלגוריתם הוא רקורסיבי אלגוריתם•
הבעיה של יותר פשוטים מקרים על עצמו את מפעיל ,מסוימת
האלגוריתם יכלול כלל בדרך .(בעיות תתי על :רבים ובמקרים)
הפתרון שבה ברמה הרקורסיה להפסקת שיביא ,"עצירה תנאי"
.אינסופית לולאה זו תהיה כן לא שאם ,מראש נתון
28
Shayke Bilu PhD SCE-Chapter-12-Recrusion
29
רקורסיה
פונקציה ידי על כלל בדרך ממומשת הרקורסיה ,טכנית מבחינה•
של במקרה ,לה שקוראת לפונקציה או) לעצמה שקוראת
נשמרת כזאת קריאה בכל ,הריצה בזמן .(הדדית רקורסיה
הפונקציה של המקומיים המשתנים ואוסף החזרה כתובת
.שבזכרון הקריאות במחסנית
הערכים האלה נשלפים מהמחסנית , בסוף ביצוע כל פונקציה•
.מתפנה, כל הזיכרון שנדרש לחישובה, כך שבסיום הרקורסיה
בזמן , מאחר שכל קריאה רקורסיבית נשמרת במחסנית המחשב•
דורשת הרקורסיה זיכרון בגודל פרופורציונלי , החישוב
.לעומקה
29
Shayke Bilu PhD SCE-Chapter-12-Recrusion
30
רקורסיה
ידי על זו זיכרון מדרישת להימנע אפשר ,פשוטות ברקורסיבית•
ברקורסיבית .שקול איטרטיבי לאלגוריתם הרקורסיה תרגום
ואז במחסנית שימוש ללא זאת לעשות ניתן לא ,יותר מורכבות
.בזיכרון חיסכון למעשה אין
אלגוריתם רקורסיבי פשוט ובהיר יותר , מסוימיםבמקרים •
.שקול איטרטיבימאלגוריתם
אלגוריתמים רקורסיביים נתמכים במרבית שפות התכנות על •
. ידי תמיכה של השפה בקריאה רקורסיבית של פונקציות
30
Shayke Bilu PhD SCE-Chapter-12-Recrusion
31
רקורסיה
ישנה (בכלל לפונקציות לקריאות כמו) רקורסיביות לקריאות•
תכנות שפות מבצעות ולכן ,התוכנית של הריצה בזמן עלות
.פונקציונליות שפות ובפרט ,רבות
רקורסית" הנקראות) רקורסיביות קריאות של אופטימיזציה•
לקוד רקורסיביות קריאות באמצעות הנכתב קוד והופכות "(זנב
.לולאות באמצעות בפועל המבוצע לינארי
.איטרטיביתכל אלגוריתם רקורסיבי ניתן למימוש בצורה •
מזו ( מבחינת זמן ריצה)לעיתים הגרסה הרקורסיבית יעילה •
.האיטרטיבית אך לא תמיד
31
Shayke Bilu PhD SCE-Chapter-12-Recrusion
32
רקורסיה
, האיטרטיביתמקרים ההגדרה הרקורסיבית קצרה מזאת בהרבה •
והיא ההגדרה הטבעית למה שרוצים לחשב
.חד ערכי-עצירה חדתנאי חובה להגדיר לפונקציה רקורסיבית •
חד ערכי הפונקציה הרקורסיבית -ללא הגדרת תנאי עצירה חד•
.הופכת לאינסופית
כ נעביר לפונקציה רקורסיבית פרמטר שיקטן בכל קריאה "בד•
(.הבעיה מימדהקטנת )רקורסיבית עד לסיומה
כאשר . פרמטר זה הוא המגביל את מספר הקריאות לרקורסיה•
יתקיים תנאי העצירה , (מקרה הבסיס)יהיה קטן מספיק הפרמטר
(ולא תבוצע קריאה רקורסיבית נוספת)ותסתיים הרקורסיה
32
Shayke Bilu PhD SCE-Chapter-12-Recrusion
: הגדרת רקורסיה במתמטיקה•
שמוגדרת באופן רקורסיבי באמצעות נוסחת סדרה
י האיברים "שבה כל איבר מוגדר עסדרה זאת נסיגה
. בסדרההקודמים
an=an-1+d , a1=3: חשבוניתסדרה •
an=an-1*q , a1=4: הנדסיתסדרה •
: רקורסיביתפונקציה •
עקיף דרך הקוראת לעצמה באופן ישיר או פונקציה
.מחייבת תנאי עצירה וסגירה חד ערכי, פונקציית עזר
רקורסיה33
Shayke Bilu PhD SCE-Chapter-12-Recrusion
n ! == n* (n-1( * … * 1
int factorial(int n)
{
if (n==0)
return 1;
return n*factorial(n-1);
}
int factorial(int n)
{
int fact =1;
while (n >= 1)
{
fact *=n;
n--;
}
return fact;
}
n ! == n * (n-1) !
י רקורסיה"חישוב עצרת רגיל ע
קריאה רקורסיבית לפונקציה עד אשר
חישוב רגיל של עצרת מהמספר 0 -הופך ל nערכו של המשתנה
35
עצירת הפונקציה: לב-נקודות לתשומת
תנאי שלב שבאיזשהו לוודא יש ,תסתיים שהתוכנית כדי
.לנצח תימשך הרקורסיה קיומו ללא ,יתקיים העצירה
מכל לולאה של הסיום לתנאי זהה הוא זה עצירה תנאי
.סוג
שהועבר פרמטר אותו עם לפונקציה קוראים והיינו במידה
ולא factorial(n) כותבים היינו אם לדוגמא) אליה
factorial(n-1)), תנאי אל מתקדמים היינו לא אז
.אינסוף עד עצמה על חוזרת הייתה והפונקציה ,העצירה
כי מניחים הבאה בדוגמה n 5 הוא.
Shayke Bilu PhD SCE-Chapter-12-Recrusion
36
רקורסיביות Cדוגמאות נוספות לפונקציות
unsigned factorial(unsigned n)
{
if(n <= 1)
return 1;
return (n * factorial(n-1));
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
37
Shayke Bilu PhD SCE-Chapter-12-Recrusion
סכום הספרות של מספרפונקציה המחשבת את כתבו .
int digsum(int x)
}
int res;
if (x==0)
{
res=0;
return res;
}
else
res=x%10+digsum(x/10);
return res;{
סכום ספרות של מספר –תרגול רקורסיה 38
חישוב חזקה באופן רקורסיבי
(:שלילי-למעריך שלם ואי)ההגדרה הרקורסיבית
an = a . an-1, a0=1
והפונקציה ב- C:
double power(double base, double exp)
{
if (exp<1)
return 1;
return base * power(base, exp-1);
}
במעריך שלילי כמו בחיוביאפשר לטפל
Shayke Bilu PhD SCE-Chapter-12-Recrusion
39
ההגדרה היא, אם יתכן מעריך שלילי:
n :a-n = 1/an<0עבור
n≥0 :an = a . an-1, a0=1עבור
הפונקציה ב- C:
double power(double base, int exponent)
{
if (exponent < 0) return 1/power(base, -exponent);
if (exponent==0) return 1;
return base * power(base, exponent-1);
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
חישוב חזקה באופן רקורסיבי40
Shayke Bilu PhD SCE-Chapter-12-Recrusion
.חזקה של מספר שלםכתבו פונקציה המחשבת •
:פתרון•
int power(int base, int exponent)
{
if (exponent == 0)
return 1;
return base * power(base, exponent -1);
}
(שלמים)חישוב חזקה –תרגול רקורסיה 41
Shayke Bilu PhD SCE-Chapter-12-Recrusion
: תרגיל
של המכפלה את המחשבת רקורסיבית פונקציה כתבו .א
.בלבד חיבור באמצעות איברים שני
המחשבת נוספת רקורסיבית פונקציה כתבו מכן לאחר .ב
חיסור פעולות באמצעות מספרים שני של החלוקה את
.בלבד
שתי את ומבצעת מספרים שני הקולטת תוכנית כתבו .ג
ומדפיסה המספרים לשני והחלוקה הכפל של ,הפונקציות
.התרגילים תוצאת את
תרגול רקורסיה 42
Shayke Bilu PhD SCE-Chapter-12-Recrusion
: פתרון•
#include <stdio.h>
int mul(int mis1, int mis2)
{
if (mis2==1)
return mis1;
return mis1 + mul(mis1,mis2-1);
}
כפל בין מספרים –תרגול רקורסיה 43
Shayke Bilu PhD SCE-Chapter-12-Recrusion
:פתרון•
int div(int mis1, int mis2)
{
if (mis2>mis1)
return 0;
return 1 + div(mis1 - mis2 , mis2);
}
חילוק בין מספרים שלמים –תרגול רקורסיה
44
Shayke Bilu PhD SCE-Chapter-12-Recrusion
:ראשית תוכנית•
int main()
}
int num1,num2;
printf("Enter two nums for div\n");
scanf("%d%d",&num1,&num2);
printf("Div num1/num2: %d\n",div(num1,num2));
printf("\n\nEnter two nums for mull\n");
scanf("%d%d",&num1,&num2);
printf("Mul num1*num2: %d\n",mul(num1,num2));
return 0;
{
חילוק בין מספרים שלמים –תרגול רקורסיה
45
Shayke Bilu PhD SCE-Chapter-12-Recrusion
תרגול רקורסיה
רצףכתוב תוכנית הכוללת פונקציה רקורסיבית הקולטת •
.אותועד ללחיצה על מקש האנטר ומדפיסה תווים
#include <stdio.h>
void wrt_it();
int main()
{
printf("Input a line\n");
wrt_it();
printf("\n");
return 0;
}
46
Shayke Bilu PhD SCE-Chapter-12-Recrusion
:פתרון הפונקציה הרקורסיבית•
void wrt_it()
{
char ch;
scanf("%c", &ch);
printf("%c", ch);
if (ch != '\n')
wrt_it();
}
תרגול רקורסיה 47
Shayke Bilu PhD SCE-Chapter-12-Recrusion
להתחלההדפס את הקלט מהסוף הפעם -המשך תרגיל •
:פתרון התוכנית הראשית•#include <stdio.h>
void wrt_it();
int main()
{
printf("Input a line\n");
wrt_it();
printf("\n");
return 0;
}
תרגול רקורסיה 48
Shayke Bilu PhD SCE-Chapter-12-Recrusion
:הפונקציה הרקורסיביתפתרון •
void wrt_it()
{
char ch;
scanf("%c", &ch);
if (ch != '\n')
wrt_it();
printf("%c",ch);
}
תרגול רקורסיה 49
הגדרת נוסחאות: רקע לרקורסיה
דרך מקובלת להגדיר נוסחה או פעולה מתמטית היא פשוט , כידוע
.לרשום את שלבי החישוב שלה
(חישוב עצרת של מספר בשלבים): דוגמאות
n!=1*2*3*….*n
an= a*a*…..*a
n פעמים
שלב-אחר-מקובל גם לחשב את ערך הנוסחה שלב .
:למשל ניתן לכפול במספר העוקב בכל שלב
4!=1*2*3*4=2*3*4=6*4=24
Shayke Bilu PhD SCE-Chapter-12-Recrusion
51
דרך נוספת להגדיר נוסחאות מאפשרת לרשום את כל שלביאפשר להגדיר את הערך של השלב האחרון בעזרת , החישוב
.תוצאות השלבים שלפניו
ידי-במקום להגדיר עצרת על, למשל:
n!=1*2*3*….*n
ידי-אפשר להגדיר על:
n!=n*(n-1)!
1=!1: בצירוף ההגדרה ההתחלתית .
ואז החישוב יהיה:
4!=4*3!=4*3*2!=4*3*2*1!=4*3*2*1=4*3*2=4*6=24
Shayke Bilu PhD SCE-Chapter-12-Recrusion
הגדרת נוסחאות: רקע רקורסיה
52
הגדרה" נקראת ההגדרה הקודמים השלבים לפי אותו התהליך של "רקורסיה נוסחת" או ,"רקורסיבית
.מבצעים
כלשהו התחלתי ערך עבור התוצאה את לציין צורך יש בעצם הנוסחה חישוב אחרת כי ,"(הרקורסיה בסיס)" .מסתיים לא
פירוט לפי גם ולחשב להגדיר ניתן רקורסיבי חישוב כל ."(איטרטיבית הגדרה)" השלבים
Shayke Bilu PhD SCE-Chapter-12-Recrusion
הגדרת נוסחאות: רקע רקורסיה
53
דוגמא נוספת:
:ידי-אפשר להגדיר חזקה על, an=a*a*…..*a: במקום
an =a*an-1, a0=1
16=1*16=1*4*4=40*4*4=41*4=42: ואז
. זו הגדרה שקולה של נוסחאות
Shayke Bilu PhD SCE-Chapter-12-Recrusion
הגדרת נוסחאות: רקע רקורסיה
54
Shayke Bilu PhD SCE-Chapter-12-Recrusion
,בהרבה קצרה הרקורסיבית ההגדרה ,רבים במקרים•
מזו למחשב מקודד כ"ואח שנכתב טקסט מבחינת
.האיטרטיבית
ההגדרה היא הרקורסיבית ההגדרה ,מסוימים במקרים•
.לחשב שרוצים מה של ביותר והנוחה הטבעית
הגדרה יש רקורסיבית הגדרה שלכל לזכור יש•
,יותר ארוכה היא כי יתכן אמנם ,שקולה איטרטיבית
מקרה בכל אך נוספים משתנים מספר וכוללת מורכבת
.קיימת היא
?מדוע נחוצה לנו הגדרה זו55
Shayke Bilu PhD SCE-Chapter-12-Recrusion
אחת פעם מתבצעת רקורסיבית הגדרה כי לזכור יש•
וחוזר ראשון משלב מתחיל הממוחשב התהליך אולם
של הסיום לתנאי להגעה עד רקורסיבי באופן
.הרקורסיה
הפונקציה אחרת כי עצירה תנאי להגדיר חובה•
.לאינסופית הופכת הרקורסיבית
מועבר העצירה בתנאי המוגדר המשתנה כלל בדרך•
ישירות נקלט הוא לעיתים אך הראשית מהתוכנית
.לפונקציה
?מדוע נחוצה לנו הגדרה זו56
כל איבר מוגדר כסכום של שני האיברים י'פיבונצבסדרת .שלפניו
1שני האיברים הראשונים הם תמיד:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,….
ההגדרה הטבעית עבור האיבר ה- n בסדרה הזאת היא:
Fib(n)=Fib(n-1)+Fib(n-2)
כאשר:
Fib(1)=1, Fib(2)=1
Shayke Bilu PhD SCE-Chapter-12-Recrusion
דוגמא להגדרה רקורסיבית57
כלומר) נוחה אינה זה במקרה ,האיטרטיבית ההגדרה .(Fib(n) של מפורשת נוסחה
לנוסחת רקורסיבית הגדרה לבצע וקל נוח יותר הרבה .י'פיבונצ
החישוב:
Fib(4)=Fib(3)+Fib(2)=Fib(2)+Fib(1)+1=1+1+1=3
Shayke Bilu PhD SCE-Chapter-12-Recrusion
דוגמא להגדרה רקורסיבית58
זהו חישוב מסובך ומורכב הבא למצוא את מספרו של :לפי מספרו הסידורי י'פיבונצהאיבר הרצוי בסדרת
מספר בסדרה:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…
מספר סידורי:
1, 2, 3, 4, 5, 6, 7 , 8 , 9 , 10 , 11…
Shayke Bilu PhD SCE-Chapter-12-Recrusion
דוגמא להגדרה רקורסיבית59
Shayke Bilu PhD SCE-Chapter-12-Recrusion
י'פיבונצלמציאת מספר אטרטיביתפונקציה •int fib_iter(int number)
{
int prev1 = 0, prev2 = 1, current, count;
for (count=0; count<number; count++ )
{
current = prev1 + prev2;
prev1 = prev2;
prev2 = current;
}
return current;
}
י'פיבונצ –תרגול רקורסיה 60
Shayke Bilu PhD SCE-Chapter-12-Recrusion
י'פיבונצרקורסיבית למציאת מספר פונקציה •
int fib_rec(int number)
{
if (number<= 1)
return number;
else
return fib_rec(number-1)+fib_rec(number-2);
}
י'פיבונצסדרת –תרגול רקורסיה 61
משתנים: לב-נקודות לתשומת
שהוגדרו משתנים ,עצמה מתוך לפונקציה כשקוראים .בזיכרון נשארים הקוראת בפונקציה
מסתיימת שהפונקציה עד בזיכרון נשארים המשתנים.
את למלא עלול זה ,רבות רקורסיביות קריאות נבצע אם .לתקיעה ולעיתים לעומס ולגרום ,המחשב של הזיכרון
חדש מקום נידרש לפונקציה קריאה כל שעבור לציין יש שאליה הנקודה עבור גם בזיכרון המחשב י"ע המוקצה
,להחזיר צריכה שהיא הערך עבור וגם לחזור צריכה היא .במשתנים נחסוך אם גם רב מקום שנידרש כך
Shayke Bilu PhD SCE-Chapter-12-Recrusion
63
בהירות: לב-נקודות לתשומת
יתרון יש ברקורסיה לשימוש כי טענה ישנה אחד מצד
את באמצעותה לכתוב יותר קל שבהם מסוימים במקרים
.החישוב
רקורסיבית הגדרה למצוא קל תמיד לא ,שני מצד
באופן שנכתבו תוכניות להבין קל תמיד ולא ,לפונקציה
.רקורסיבי
נוחים שבאמת במקרים ברקורסיה להשתמש נבחר לכן
.לכך
Shayke Bilu PhD SCE-Chapter-12-Recrusion
64
יעילות: לב-נקודות לתשומת
למספר זהה היה לפונקציה הקריאות מספר ,שראינו במקרה מקרים יתכנו .לולאה ידי-על בחישוב עושים שהיינו השלבים
עלול הריצה זמן ואז ,בהרבה רבות לקריאות נזדקק שבהם .איטי יותר הרבה להיות
ורוצים במידה ברקורסיה מאד נפוץ סטטי במשתנה שימוש :כך להגדירו יש סוכם משתנה רקורסיבית לפונקציה להכניס
static int sum=0;
רקורסיבית קריאה כל להתאפס לא למשתנה תגרום זו הגדרה .תוצאות בתוכו לסכום לנו ולאפשר
Shayke Bilu PhD SCE-Chapter-12-Recrusion
65
חישוב רקורסיבי – י'פיבונצסדרת
להלן סדרה המדגימה נוסחה המוגדרת באופן רקורסיבי:
fib(n)=fib(n-1)+fib(n-2), fib(1)=1, fib(2)=1
נוכל לכתוב את זה כך ב- C:
int fib (int n)
{
if ((n==1) || (n==2))
return 1;
return fib(n-1)+fib(n-2);
}
הדוגמאות הקודמות שראינוהזו לשתי מה ההבדל בין הדוגמא?
Shayke Bilu PhD SCE-Chapter-12-Recrusion
66
כל קריאה לפונקציה הזאת עםn>2 , יוצרת שתי קריאותאז כל אחת מהן , n>2אם גם בהן , נוספות לפונקציה
.וכן הלאה, יוצרת שתי קריאות נוספות עבורn נקבל מספר עצום של , 50למשל , קטן יחסית
n-ה)שימלאו את הזיכרון במשתנים , קריאות לפונקציה (.של כל הקריאות לפונקציה
int fib (int n) { if ((n==1) || (n==2)) return 1; return fib(n-1)+fib(n-2); }
Shayke Bilu PhD SCE-Chapter-12-Recrusion
י'פיבונצחישוב סדרת 67
fib תיעוד קריאות לפונקציה
number מספר קריאות ערך
1 1 1
2 1 1
3 2 3
23 28657 92735
24 46368 150049
Shayke Bilu PhD SCE-Chapter-12-Recrusion
68
יעילות - י'פיבונצסדרת
בעיה לנו צפויה כי נמצא היעילות מדד את כשנבחן של הבזבוז בגלל שתיארנו הרקורסיבית בפונקציה רצינית
.הקריאות מספר
לכל לחשב צריך בסדרה 23-ה האיבר את לחשב מנת על הרקורסיבי בחישוב אבל ,שלפניו הערכים 22 את היותר
יחושבו כלומר ,לפונקציה קריאות אלפי עשרות יתבצעו .ערכים אלפי עשרות
הרקורסיבית הפונקציה תמיד לא :המתבקשת המסקנה .מהאיטראטיבית יותר יעילה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
69
יעילות - י'פיבונצסדרת
כל ,במחשב חדשה איטרציה פותחת לפונקציה קריאה כל את ומאטה זיכרון ממשאבי מורכבת כזו חדשה איטרציה
.המעבד מהירות
לחוסר הגורם משאבים לבזבוז גורם קריאות של רב מספר .יעילות
צורך יש האם היטב לוודא יש :המתבקשת המסקנה .אותה ומפעילים שכותבים לפני רקורסיבית בפונקציה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
70
יעילות - י'פיבונצסדרת
שמחושבים הערכים ששני היא היעילות לחוסר הסיבה ברקורסיה ולכן ,נשמרים לא הרקורסיבית בקריאה .'וכו ,fib(1), fib(2) הקריאות את פעמים הרבה יבוצעו
הן מכך המתבקשות המסקנות:
יותר לעצמה לקרוא צריכה רקורסיבית פונקציה אם1. רק ויתאפשר ,בעייתי הוא חישובה אז ,אחת מפעם
.קטנים למספרים
לכתוב ,להגדיר נצטרך גדולים מספרים עבור2. .איטרטיבית פונקציה ולהפעיל
Shayke Bilu PhD SCE-Chapter-12-Recrusion
71
Shayke Bilu PhD SCE-Chapter-12-Recrusion
המקסימלי במערךפונקציה רקורסיבית המוצאת את האיבר כתבו •int max(int mis1, int mis2)
{
if(mis1>mis2)
return mis1;
else
return mis2;
}
int max_arr(int arr[], int number)
{
if (number == 1) return arr[0];
return max(arr[0], max_arr(arr+1, number-1));
}
מספר מקסימלי במערך –תרגול רקורסיה
72
רקורסיה יכולה לשמש אותנו לא רק לחישוב נוסחאות .
ידי פתרון -אפשר להשתמש בה עבור כל בעיה שניתן לפתור על .פשוט שלה/של מקרה יותר קטן
לדוגמא אפשר לחשב סכום איברי מערך לפי סכום האיברים בלי (עוצרים כשנשאר אחד: )ועוד האיבר האחרון, האיבר האחרון
int sum_arr(int arr[], int size)
{
if (size==1)
return arr[0];
return arr[0] + sum_arr(arr+1,size-1);
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
73
סיכום איברי המערך –תרגול רקורסיה
הפונקציה הבאה בודקת האם תו נמצא במחרוזת ,
. 0אם כן ואחרת 1ומחזירה
הפונקציה נעצרת כשמגיעים לסוף המחרוזת או
.כשמצאנו את התו המבוקש
int in_str(char *str, char letter)
{
if (*str == ‘\0’) return 0;
if (*str == letter) return 1;
return in_str(str+1, letter);
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
74
מציאת תו במחרוזת –תרגול רקורסיה
עוד דוגמא –רקורסיה
של תו במחרוזת מספר ההופעותהפונקציה הבאה מחזירה את .
1אז מספר ההופעות הוא , אם התו הראשון הוא התו שמחפשים זה רק מספר , אחרת. ועוד מספר הופעותיו במקומות הבאים
(.עוצרים כשהגענו לסוף המחרוזת)הופעותיו במקומות הבאים
int in_str(char *str, char letter)
{
if (*str == ‘\0’) return 0;
if (*str == letter) return 1 +
in_str(str+1, letter);
return in_str(str+1, letter);
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
75
Recursion -רקורסיה
הניתן אלגוריתם רקורסיבי לפתרון בעיה הינו אלגוריתם
פרמטרים קטנים עבור בפתרונות של אותה בעיה לשימוש
.יותר
מתי משתמשים ברקורסיה? בעיה עם פרמטר כאשר נתונהn.
לדוגמא )בידינו פתרון לאותה בעיה עם פרמטר קטן יותר אם יש
n-1)
עבור אם הפתרון הולך בקלותn.
מגדירים את בסיס , כדי שתהליך החישוב יסתיים
זהו מקרה פשוט של הבעיה בו הפתרון ידוע : הרקורסיה
.ללא הפעלת הרקורסיהShayke Bilu PhD SCE-Chapter-12-Recrusion
77
דוגמאות -פתרון בעיות ברקורסיה
1דוגמא :
חישוב :הבעיהf(n) = n!
נניח כי נתון: f(n-1) = (n-1)!
נציג את הפתרון: f(n) = n * f(n-1)
בסיס הרקורסיה: f(0) = 1
Shayke Bilu PhD SCE-Chapter-12-Recrusion
78
דוגמאות -פתרון בעיות ברקורסיה
2דוגמא :
חישוב :הבעיהgcd(m, n)
הפתרוןנציג את:gcd(m, n) = gcd(n, m % n)
בסיס הרקורסיה: gcd(m, 0) = m
Shayke Bilu PhD SCE-Chapter-12-Recrusion
79
המשך, דוגמאות –פתרון בעיות ברקורסיה
3דוגמא :
הבעיה: f(x, n) = xn
פתרון רקורסיבי : f(x, n) = x * f(x, n-1)
בסיס הרקורסיה: f(x, 0) = 1 לכלx
Shayke Bilu PhD SCE-Chapter-12-Recrusion
80
המשך, דוגמאות –פתרון בעיות ברקורסיה
4דוגמא :
יש לקבוע האם הערך :הבעיהx נמצא במערך בגודלn הממוין .בסדר עולה
נציג את הפתרון:
אםx אזי מצאנו את ,שווה לאיבר האמצעיx.
אםx נחפש את , קטן מהאיבר האמצעי במערךx בתת המערך השמאלי n/2שגודלו
אםx נחפש את , גדול מהאיבר האמצעי במערךx בתת המערך הימני n/2שגודלו
הרקורסיהבסיס :
x (.0גודל )איננו נמצא במערך ריק
Shayke Bilu PhD SCE-Chapter-12-Recrusion
81
רקורסיה לעומת לולאות
היתרון ברקורסיה:
קל לכתיבה ולתחזוקה, וקריאפתרון מנוסח באופן אלגנטי.
"( כגון הקצאת מערך ועדכון אינדקסים)של התכנית " הנהלת החשבונות .ושקופה הן למתכנת ובוודאי למפעילנסתרת
ואין צורך , בדוגמת היפוך הקלט יוקצה זיכרון בהתאם לאורך המחרוזת .להניח חסם עליון על מספר התווים
מספר רב של קריאות לפונקציה: במימוש הרקורסיביהחיסרון
מבוסס ) איטרטיבייכול לגרום לצריכת זיכרון מופרזת בהשוואה לפתרון ( על לולאות
שקול וההפך איטרטיבילכל חישוב רקורסיבי ניתן לבנות חישוב
צריך לחשוב ולבחור את הפתרון המתאים ביותר מבחינת יעילות או נוחות
Shayke Bilu PhD SCE-Chapter-12-Recrusion
82
רקורסיביות Cדוגמאות נוספות לפונקציות
gcd – הוא שלמים מספרים שני של מקסימאלי משותף מחלק
.שניהם את שמחלק ביותר הגדול המספר
.6 הוא 18ו־ 12 של המקסימלי המשותף המחלק ,למשל
unsigned gcd(unsigned m, unsigned n)
{
if(n == 0)
return m;
return gcd(n, m%n);
} Shayke Bilu PhD SCE-Chapter-12-Recrusion
83
זמן ומקום של הפונקציות הרקורסיביותסיבוכיות
כמות ) סיבוכיות המקוםו( מספר פעולות החישוב) סיבוכיות הזמן
הן power(x,n)ושל factorial(n)של ( הזיכרון
O(n) ( גידול ליניארי עםn)
של סיבוכיות הזמן וסיבוכיות המקוםexists(a,n,x)
הןO(log n) ( גידול ליניארי עםlog n)
פשוט איטרטיביניתן לכתוב קוד , לכל אחת מהבעיות הללו
סיבוכיות זמן הזהה לזו של הקוד הרקורסיבי ובעל סיבוכיות בעל
(n-גודל קבוע שאינו תלוי ב) O(1) -מקום קטנה יותר
Shayke Bilu PhD SCE-Chapter-12-Recrusion
84
מימוש יעיל יותר של חזקה
סיבוכיות הזמן :
סיבוכיות המקום :
double power(double x, unsigned n)
{
if (n == 0) return 1;
double y = power(x, n/2);
y *= y;
if (n % 2)
y *= x;
return y;
}
n2log
n2log
Shayke Bilu PhD SCE-Chapter-12-Recrusion
85
מגדלי הנוי –פתרון בעיות ברקורסיה
נתון:
ממוט ( ארבעה במספר)כל הדיסקים להעביר את : המשימהA למוטB תוך שימוש במוט Cלפי הכללים הבאים, כמוט עזר זמני בלבד:
ממוט למוטדיסק בודד בכל צעד מותר להעביר.
על דיסק קטן באף אחד מהמוטותגדול מונח דיסק אסור מצב שבו.
1
2
3
4
A B C מוט
המקור
מוט
המטרה
מוט עזר
Shayke Bilu PhD SCE-Chapter-12-Recrusion
86
1
2
3
4
מגדלי הנוי –פתרון בעיות ברקורסיה
נניח כי ידוע כיצד מעבירים : פתרוןn-1 ממגדל מקור דיסקים
.למגדל יעד תוך שימוש במגדל עזר
2 ,1הדיסקים נעביר את, .... ,n-1 ממגדלA למגדלC תוך
.Bשימוש במגדל
דיסק נעביר אתn ממגדלA למגדלB.
2 ,1הדיסקים נעביר את, .... ,n-1 ממגדלC למגדלB תוך
.Aבמגדל שימוש
כאשר: בסיס הרקורסיה,n=0 לא עושים דבר.
Shayke Bilu PhD SCE-Chapter-12-Recrusion
87
מגדלי הנוי –מימוש פתרון ברקורסיה
void hanoi(int n, char From, char To, char Temp);
int main()
{
int n;
printf ("Enter number of discs:\n");
scanf("%d", &n);
hanoi(n, ‘A’, ‘B’, ’C’);
return 0;
} Shayke Bilu PhD SCE-Chapter-12-Recrusion
105
מגדלי הנוי –מימוש פתרון ברקורסיה
void hanoi (int n, char From, char To, char Temp)
{
if(n==1)
printf("move disc from tower %c to
tower %c\n", From, Temp);
else
{
hanoi(n-1, From, Temp, To);
printf("move disc from tower %c to tower
%c\n", From, Temp);
hanoi(n-1, To, From, Temp);
{
} Shayke Bilu PhD SCE-Chapter-12-Recrusion
106
ניתוח סיבוכיות מקום –מגדלי הנוי
בזמן נתון יש לכל היותרn+1 לפונקציה קריאות
hanoi() על מחסנית הקריאות.
בכל קריאה מוקצים משתנים בסיבוכיות מקוםO(1).
סיבוכיות המקום של האלגוריתם היאO(n).
Shayke Bilu PhD SCE-Chapter-12-Recrusion
107
ניתוח סיבוכיות זמן –מגדלי הנוי
נסמן ב- T(n) את מספר ()hanoiהקריאות לפונקציה
nהדרושות להעברת מגדל של .חישוקים
הפעולות המתבצעות עלותהינה ()hanoi-בקריאה בודדת ל
.O(1)
סיבוכיות הזמן הכוללת של .(2n)האלגוריתם הינה
T(0) = 1
T(n) = 1 + 2T(n-1)
= 1 + 2(1 + 2T(n-2))
= 3 + 4T(n-2)
...
= (2i–1) + 2i T(n-i)
...
= (2n–1) + 2nT(0)
= 2n+1 - 1
Shayke Bilu PhD SCE-Chapter-12-Recrusion
108
שבו מצב מתאר (recursion) רקורסיה המונח :הגדרה•
היא וכך עקיף באופן או ישיר באופן לעצמה קוראת פונקציה
.להתחלה מהסוף כלומר נסיגתית בצורה עבודתה מבצעת
מנת על רקורסיביות בפונקציות להשתמש נוח :שימוש•
.רקורסיבי אופי בעלות בעיות לפתור
ממד את להקטין תהיה השיטה ,כללי באופן :יחסי יתרון•
ולהשתמש קטן היותר הממד על הבעיה את לפתור ,הבעיה
יותר אחד בממד הבעיה את לפתור מנת על שמתקבל בפתרון
.גבוהה
רקורסיה
Shayke Bilu PhD SCE-Chapter-12-Recrusion
110
Shayke Bilu PhD SCE-Chapter-12-Recrusion
משתנים סטאטיים –תזכורת
;static int sum=0 :הבא באופן מגדירים• לאתחל חייבים כאשר בלבד ההגדרה בשורת לאתחל ניתן•
!!!קבוע בביטויי
אוטומטית אותם תאתחל המערכת ,אותם מאתחלים לא אנחנו אם•
.לאפס
הם שבה הפונקציה רק הוא סטאטיים משתנים של -scopeה•
הפונקציה שביצוע אחרי גם להתקיים ממשיכים הם אך הוגדרו
.(התוכנית ריצת סוף עד למעשה) נגמר
בין נשמר כלשהי בפונקציה סטאטי משתנה של הערך לפיכך•
.זו לפונקציה עוקבות קריאות
111
Shayke Bilu PhD SCE-Chapter-12-Recrusion
harmonic number – 1' דוגמה מס
: מוגדר באופן הבא nהשלם ' הרמוני של המס' מס•
)(12
1...
1
11nh
nn
רקורסיבית ברצוננו לכתוב פונקציה •
rec_harmonic_num(n) אשר תדפיס למסך את הפיתוח
. h(n)של
נקבל על , rec_harmonic_num(5)הקריאה עבור , למשל•
2.28=1/5+1/4+1/3+1/2+1 :המסך
112
Shayke Bilu PhD SCE-Chapter-12-Recrusion
void rec_harmonic_sum(int n)
{
static double sum=1;
if(n==1) /*Stop condition*/
{
printf("1=%.2f\n",sum);
sum=1;
/*Must initialize the static variable "sum" so that we can call
this function repeatedly in the same program run. Make sure
you understand why!!! */
harmonic number – 1' דוגמה מס113
Shayke Bilu PhD SCE-Chapter-12-Recrusion
return;
}
printf("1/%d+",n);
sum+=1./n;
/*The "1." syntax is used in order to prevent automatic casting
to integer type (so that the expression "1/n" will be evaluated as
type double). */
rec_harmonic_sum(n-1);
/*The recursive call. */
}
harmonic number – 1' דוגמה מס114
Shayke Bilu PhD SCE-Chapter-12-Recrusion
abc – 2' דוגמה מס
:היא חתימתה אשר רקורסיבית פונקציה כתוב
void abc(char arr[],int lastPlace, int curPlace)
סוף אינדקס את ,ים-char של מערך תקבל הפונקציה
אנו ממנו במערך המקום שהוא שלם ומספר המערך
.בתווים המערך במילוי להתחיל מעוניינים
.0 -ל שווה זה 'מס יהיה ראשונה בקריאה
115
Shayke Bilu PhD SCE-Chapter-12-Recrusion
abc – 2' דוגמה מס
המערך את למלא האפשרויות כל את מדפיסה הפונקציה
lastPlace המקום עד ,curPlace ,שקיבלה מהמקום
A,B,C. באותיות
כל את להדפיס היא הפונקציה מטרת ,אחרות במילים
האותיות בעזרת מסוים באורך מילה ליצור האפשרויות
A,B,C.
116
Shayke Bilu PhD SCE-Chapter-12-Recrusion
abc – 2' דוגמה מס
:התוכנית הבאהעבור , למשל
void abcInvokingFun(char word[],int lengthOfWord)
{
abc(word, lengthOfWord,0);
}
void main()
{
char word[SIZE];
abcInvokingFun(word,3);
}
117
Shayke Bilu PhD SCE-Chapter-12-Recrusion
abc – 2' דוגמה מס
:העצירה תנאי
במקום נשים אז lastPlace -ל הגענו אם
את ונדפיס ,(לסוף הגענו) '\0' יש הנוכחי
.וחזור (מהתחלתה) המחרוזת
curPlace המקום על עובדים אנחנו כעת
:במערך
בו מציבים A, לפונק וקוראים' abc (עם
אשר (הבא המקום ואינדקס ,המערך כתובת
בשאר הקיימות האפשרויות כל למילוי תדאג
.המערך
את מציבים ,שחוזרים לאחר B במקום A,
במערך הבא המקום עם לפונקציה קוראים ושוב
.כפרמטר
התו לגבי הפעולה על חוזרים ל"כנ- C.
void abc(char arr[],int lastPlace, int curPlace)
{
if (curPlace == lastPlace)
{
arr[curPlace] = ' \0';
printf("%s\t",arr);
return;
}
arr[curPlace] = ‘A';
abc (arr,lastPlace,curPlace+1);
arr[curPlace] = ‘B';
abc (arr,lastPlace,curPlace+1);
arr[curPlace] = ‘C';
abc (arr,lastPlace,curPlace+1);
}
118
Shayke Bilu PhD SCE-Chapter-12-Recrusion
ABC – 2' דוגמה מס
:הפלט הבאאת נקבל
AAA AAB AAC ABA ABB ABC
ACA ACB ACC BAA BAB BAC
BBA BBB BBC BCA BCB BCC
CAA CAB CAC CBA CBB CBC
CCA CCB CCC
119
סיכום -רקורסיה
לעצמה הקוראת פונקציה היא רקורסיבית פונקציה, יותר פרמטרים עבור הפעלתה בעזרת מוגדרת כלומר .פשוטים/קטנים
תנאי בצירוף מתבצעת לפונקציה העצמית הקריאה אליו שנגיע שמובטח ,כלשהו פרמטר עבור התחלה .החישוב במהלך
לפונקציה אותה לתרגם קל ,רקורסיבית נוסחה לנו כשיש .C-ב רקורסיבית
לנו נתון לא הוא אם רקורסיבי ניסוח למצוא קל תמיד לא .איטרטיבי חישוב לבצע עדיף ולעיתים
Shayke Bilu PhD SCE-Chapter-12-Recrusion
120
סיכום -רקורסיה
אחת מפעם יותר לעצמה קוראת הפונקציה שלב בכל אם, וזיכרון זמן הרבה ידרשו קטנים ערכים עבור כבר אז
.לחישוב
בעייתי הוא הרקורסיבי החישוב כי לחשוב ניתן ,לכן .כזה במקרה
אז ,שלב בכל אחת פעם רק לעצמה קוראת הפונקציה אם ואלגנטית קצרה כדרך לשמש יכולה רקורסיבית כתיבה
.נוספות ופעולות חישובים לביצוע
בתרגול יוצגו נוספות דוגמאות.
Shayke Bilu PhD SCE-Chapter-12-Recrusion
121
תרגילי כיתה
ומדפיסה שלם מספר המקבלת רקורסיבית פונקציה כתבו1.
.להתחלה מהסוף הפוך אותו
הרקורסיבית הפונקציה 1234 המספר בהינתן :דוגמא
.4321 תדפיס
הבדיקה אחרי ההדפסה את נבצע אם המסך על יופיע מה?
חדש מספר שתייצר הרקורסיבית הפונקציה את שדרג
.מהמקורי הפוך
.למחרוזת דבר אותו שעושה רקורסיבית פונקציה כתבו2.
התו את המחזירה רקורסיבית פונקציה לבנות נסה3.
.המקסימלי
Shayke Bilu PhD SCE-Chapter-12-Recrusion
123
תרגילי כיתה
,למערך שלמים ערכים 10 עד הקולטת תוכנית כתבו4.
ןאת המקסימאלי הערך את ומוצאת אותו מדפיסה
. (קלט סוף מציין -1 המספר של קלט)במערך מיקומו
:יותר קטנות בעיות לארבע הבעיה את לפרק ניתן ,כך לשם(aהמערך את שקולטת רקורסיבית פונקציה כתבו.
(bהמקסימאלי הערך את שמחזירה רקורסיבית פונקציה כתבו.
(cהערך של מיקומו את המוצאת רקורסיבית פונקציה כתבו
.שבמערך המקסימלי
(dהמערך איברי את המדפיסה רקורסיבית פונקציה כתבו.
יש המערך לתוך ערך של קליטה סיבוב בכל כי להקפיד מומלץ
!!! ומבוקר ידוע יציאה תנאיShayke Bilu PhD SCE-Chapter-12-Recrusion
124
תרגילי כיתה
תו ,s מחרוזת מקבלת אשר רקורסיבית פונקציה כתוב5.
ch, שלם ומספר n.
ה המופע את תחפש הפונקציה- n-של י ch במחרוזת s
.שלו האינדקס את ותחזיר
המחרוזת בהינתן :דוגמא "axftbbncf“ , התו b, והשלם
.2 תחזיר הפונקציה (n עבור) 2
התו ‘b’ כתובת ,החמישי מהמקום החל פעמיים מופיע
.s במחרוזת ,4 מספר
Shayke Bilu PhD SCE-Chapter-12-Recrusion
125
Shayke Bilu PhD SCE-Chapter-12-Recrusion
תרגילי כיתה
:נתונה הפונקציה הרקורסיבית הבאה6.#include <stdio.h>
int secret( int n)
{
if( n<0 )
return 1 + secret ( -1 * n);
if ( n<10 )
return 1;
return 1 + secret( n/10 );
}
(a מה הערך שלsecret(-4321) ו- secret(12345) ?
(b מה מבצעת הפונקציהsecret שליליעבור פרמטר חיובי ועבור?
(cכתוב פונקציה זו מחדש בצורה לא רקורסיבית.
126
Shayke Bilu PhD SCE-Chapter-12-Recrusion
תרגילי כיתה
:עיין בפונקציה הבאה7.
int what(int a, int b)
{
if(!a && !b)
return 1;
if(a > b)
return a * what(a-1, b);
return b * what(a, b-1);
}
127
Shayke Bilu PhD SCE-Chapter-12-Recrusion
תרגילי כיתה
חיוביים )שליליים -ל מקבלת שני ערכים אי"שהפונקציה הנבהנחה
(:בדף התשובות)סמן את כל התשובות הנכונות , (או אפס
שקר -אינסופית הפונקציה נכנסת לרקורסיה 1.
שקר - 0הערך המוחזר של הפונקציה תמיד 2.
שקר - 0הערך המוחזר של הפונקציה יכול להיות 3.
שקר - 1הערך המוחזר של הפונקציה תמיד 4.
אמת - 1הערך המוחזר של הפונקציה יכול להיות 5.
, אם הערכים לא גדולים מידי, b -ו a חיובייםבקבלת שני ערכים 6.
אמת - - !a! x bשל מחזירה את הערך הפונקציה
שקר -לעיל אף לא אחת מהתשובות 7.
128
תרגילי כיתה
פעולת לתאור מעקב טבלת בנה ,רקורסיבית פונקציה לפניך8.
:התוצאה את והצג 123 המספר את וקיבלה במידה הפונקציה
int what (int n)
{
int k;
if(n<10) return n;
else
{
k = what ((n/100)*10 + n%10);
return (k*10 + (n%100) /10);
}
}
Shayke Bilu PhD SCE-Chapter-12-Recrusion
129
תרגילי כיתה
:הבאות המשימות את המבצעת תוכנית כתוב9.
מספרים 25-ב מלא ממדי חד מערך ומייצרת מגדירה•
.רנדומליים
.המערך את בועות מיון שתמיין פונקציה מתפעלת•
חיפוש לביצוע רקורסיבית פונקציה תתפעל התוכנית•
.מהמשתמש הנקלט מספר של הממוין במערך בינארי
הרקורסיבית בפונקציה נמצא שנקלט והמספר במידה•
.מתאימה הודעה תציג
Shayke Bilu PhD SCE-Chapter-12-Recrusion
130