מבוא לתכנות ב- JAVA תרגול 8
תזכורת - מבנה של פונקציה רקורסיבית.2 פונקציה רקורסיבית מורכבת משני חלקים עיקריים 1. תנאי עצירה: מקרה/מקרים פשוטים בהם התוצאה לא מצריכה קריאה רקורסיבית לחישוב צעד רקורסיבי: קריאה לפונקציה עם קלט קטן יותר או בעיה פשוטה יותר )הקטנת הבעיה( המקרבת אותנו לתנאי העצירה לצורך חישוב התוצאה המוחזרת
תרגיל כתבו פונקציה רקורסיבית המבצעת חילוק שלמים עבור מספרים חיוביים. לדוגמה: = 3 divide(7,2) הדרכה: כמה פעמים 2 נכנס ב 7?
פתרון public static int divide(int a, int b) { if (b == 0) return -1; else if (a < b) return 0; else return 1 + divide(a - b, b); 3 +1 +1 +1 Divide(9,3) a 9 b 3 Divide(6,3) a 6 b 3 Divide(3,3) a 3 b 3 0 Divide(0,3) a 0 b 3
פתרון public static int divide(int a, int b) { if (b == 0) return -1; else if (a < b) return 0; else return 1 + divide(a - b, b); 2 +1 +1 Divide(21,10) a 21 b 10 Divide(11,10) a 11 b 10 0 Divide(1,10) a 1 b 10
תרגיל איך נשנה את הפונקציה השארית במקום? בכדי שתחזיר את
תרגיל כתבו פונקציה רקורסיבית שמקבלת 2 מחרוזות str1, str2 ובודקת האם str1 היא תת מחרוזת של.str2 המחרוזת str1 צריכה להופיע בתוך str2 לפי סדר האותיות אבל לאו דווקא ברצף דוגמא המחרוזת abc היא תת מחרוזת של deafbc"
פתרון public static boolean contains(string str1, String str2){ if (str1.equals("")){ return true; if (str2.equals("")){ return false; if (str1.charat(0) == str2.charat(0)){ return contains(str1.substring(1),str2.substring(1)); return contains(str1, str2.substring(1));
תרגיל - משולש פסקל משולש פסקל הוא סידור של מספרים בצורת משולש, הנבנה באופן הבא: הקודקוד העליון של משולש זה מכיל את המספר 1, וכל מספר במשולש מהווה את סכום שני המספרים שנמצאים מעליו )המספרים שנמצאים על שוקי המשולש הם כולם 1(. n 0 1 1 1 1 2 1 2 1 המספר ה- m בשורה ה- n, נותן את 3 1 3 3 1 התשובה לשאלה "בכמה דרכים שונות אפשר לבחור m עצמים מתוך 4 1 4 6 4 1 5 1 5 10 10 5 1 n עצמים?" )מקדם בינומי(. m 0 1 2 3 4 5
תרגיל משולש פסקל נכתוב פונקציה רקורסיבית (m pascal(int,n int שתחשב המופיע בשורה n ובעמודה m במשולש פסקל. המספר את תאור האלגוריתם תנאי עצירה: אם m הוא 0 חוקיות הקלט: שגיאה בקלט. n נחזיר ערך 1. אם n=m ו- m הם שלמים אי-שליליים. אם m>n קריאות רקורסיביות על קלט קטן יותר: קריאה אחת עם 1-n קריאה שנייה עם 1-n ו- m ו 1-m )המספר מעל( )המספר מעל ומשמאל( נחזיר ערך 1. שילוב התוצאות לקבלת תשובה: החזרת סכום של הערכים שהתקבלו משתי הקריאות הרקורסיביות. נציין שיש
פתרון - משולש פסקל // Pascal number in row n and column m. public static int pascal(int n, int m){ int ans; if (m<0 n<0 m>n) { ans = -1; else if (m==0 n == m) { ans = 1; else { ans = pascal(n-1,m) + pascal(n-1,m-1); return ans; מבוא למדעי המחשב, בן גוריון 11
תרגיל כתבו פונקציה רקורסיבית שמחשבת את מספר הדרכים לעלות n מדרגות כאשר בכל צעד עולים מדרגה אחת או שתי מדרגות public static int takestairs(int n){
פתרון public static int takestairs(int n){ if (n == 1){ return 1; if (n == 2){ return 2; return takestairs(n-1) + takestairs(n-2); הפתרון נראה מוכר?
שאלה ממבחן )2014 מועד א( נתונה התוכנית הבאה: public static int what1(int n, int m){ if (n == 0 && m == 0) return 0; if (n > m) return n + what1(n-1,m); return what1(n,m-1)-m; //what1 public static void main(string[] args){ System.out.println(what1(4,3)); System.out.println(what1(5,2)); //main א. )14 נק'( מהו הפלט של התוכנית הנ"ל )חובה מעקב(? ב. )6 נק'( מהו יעודה של הפעולה? what1
פתרון what1(4,3) 4 סעיף א : מעקב =4 what1(4,3) 4 + what1(3,3) 0 what1(3,2) - 3 3 3 + what1(2,2) 0 what1(2,1) - 2 2 2 + what1(1,1) 0 what1(1,0) 1 + - 1 what1(0,0) 1
פתרון what1(5,2) 12 סעיף א : מעקב what1(5,2)=12 5 + what1(4,2) 7 4 + what1(3,2) 3 3 + what1(2,2) 0 what1(2,1) - 2 2 2 + what1(1,1) 0 what1(1,0) 1 + - 1 what1(0,0) 1
פתרון סעיף א: פלט התוכנית: 4 12 סעיף ב: הפונקציה סוכמת את כל המספרים החיובים מ 1 עד n ומורידה מהם את כל המספרים החיובים מ 1 עד m. כלומר אם m<n הפונקציה מחשבת את הסכום (m+1)+(m+2)+ + n אם m>n הפונקציה what1 מחשבת את הסכום -((n+1)+(n+2)+ +m)
)SUSU( בעיית Subset Sum בהנתן מערך של משקולות ומשקל נוסף, נרצה לבדוק האם ניתן להרכיב מהמשקולות משקל השווה למשקל הנתון. weights={1,7,9,3 Sum = 12 דוגמא לקלט: במקרה זה הפונקציה תחזיר true ו- 3 ולקבל את הסכום 12. כי ניתן לחבר את המשקולות 9 18
אסטרטגיית פתרון נסתכל על האיבר הראשון SUSU weights[0] weights[1] weights[n], sum weights[0] יתווסף לסכום נותר לפתור בעיה קטנה יותר: האם ניתן להרכיב את הסכום sum-weights[0] מבין המשקולות שבתאים weights[1,,n-1] weights[0] לא יתווסף לסכום נותר לפתור בעיה קטנה יותר: האם ניתן להרכיב את הסכום sum מבין המשקולות שבתאים weights[1,,n-1] SUSU weights[1] weights[n] SUSU weights[1] weights[n] sum sum-weights[0]
אסטרטגיית פתרון המשך נעבור על כל האיברים במערך ונבחן אפשרויות בהן איבר נבחר או לא נבחר. קיימים שני מקרי בסיס:.1.2 הגענו לסכום הדרוש, או במילים אחרות - הסכום הנותר הינו אפס. הגענו לסוף המערך עברנו על כל האיברים ולא מצאנו צירוף של איברים שסכומם שווה לסכום הנדרש. 20
פתרון פתרון זה קל להציג כפונקציה רקורסיבית: calcweights(int[] weights, int i, int sum) אשר מקבלת בנוסף על sum ו- weights פרמטר נוסף i שמייצג את המשקולת שבודקים כעת ומחזירה תשובה לשאלה: האם ניתן להרכיב את הסכום מבין קבוצת המשקולות שבתת המערך.weights[i weights.length] public static boolean calcweights(int[] weights, int sum) { return calcweights(weights, 0, sum); 21
פתרון )המשך( public static boolean calcweights(int[] weights, int i, int sum) { boolean res = false; if (sum == 0) res = true; else if (i >= weights.length) res = false; else res =( calcweights(weights,i+1,sum-weights[i]) calcweights(weights, i+1, sum) ); return res; 22