מבוא לתכנות ב- JAVA תרגול 8
תזכורת - מבנה של פונקציה רקורסיבית.2 פונקציה רקורסיבית מורכבת משני חלקים עיקריים 1. תנאי עצירה: מקרה/מקרים פשוטים בהם התוצאה לא מצריכה קריאה רקורסיבית לחישוב צעד רקורסיבי: קריאה לפונקציה עם קלט קטן יותר או בעיה פשוטה יותר )הקטנת הבעיה( המקרבת אותנו לתנאי העצירה לצורך חישוב התוצאה המוחזרת
שאלה ממבחן )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
פתרון סעיף א : מעקב =4 what1(4,3) what1(4,3) 4 public static int what1(int n, int m){ 4 + what1(3,3) what1(3,2) 0-3 3 //what1 if (n == 0 && m == 0) return 0; if (n > m) return n + what1(n-1,m); return what1(n,m-1)-m; public static void main(string[] args){ 3 + what1(2,2) 0 //main System.out.println(what1(4,3)); System.out.println(what1(5,2)); 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) 5 + what1(4,2) 4 + 12 public static int what1(int n, int m){ what1(3,2) 3 + 7 what1(2,2) 3 0 //what1 if (n == 0 && m == 0) return 0; if (n > m) return n + what1(n-1,m); return what1(n,m-1)-m; public static void main(string[] args){ //main System.out.println(what1(4,3)); System.out.println(what1(5,2)); 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. 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){ //main System.out.println(what1(4,3)); System.out.println(what1(5,2));
שאלה ממבחן )2016 סמס' ב מועד א'(
שאלה ממבחן )2016 סמס' ב מועד א'( פתרון
הפרד ומשול שיטה בה מחלקים את הבעיה המקורית ל 2 או יותר תתי בעיות מאותה הצורה )או צורה דומה לה(, עד שהבעיות הופכות לפשוטות כדי שניתן יהיה לפתור אותן ישירות. לאחר מכן הפתרונות לתת הבעיות משולבים יחד כדי לתת פתרון לבעיה המקורית. איך למצוא מחט בערימת שחת?
דוגמא לשימוש בעקרון של הפרד ומשול מציאת מקסימום במערך אלגוריתם רקורסיבי בשיטת הפרד ומשול למציאת מקסימום במערך: מצא מקסימום בחצי המערך השמאלי באופן רקורסיבי מצא מקסימום בחצי המערך הימני באופן רקורסיבי החזר את המקסימום מבין התוצאות שקיבלת max1 max2 maxarray = maximum between max1,max2
דוגמא לשימוש בעקרון של הפרד ומשול מציאת מקסימום במערך השלימו את הקוד כך שהפונקציה תמצא את המקסימום במערך בשיטת הפרד ומשול public static int findmax(int[] arr, int begin, int end){ int max1,max2; Base case Recursive steps if (max1 > max2){ return max1; return max2;
פתרון public static int findmax(int[] arr, int begin, int end){ int max1,max2; if (begin == end){ return arr[begin]; int middle = (begin + end) / 2; max1 = findmax(arr, begin, middle); max2 = findmax(arr, middle+1, end); if (max1 > max2){ return max1; return max2;
תרגיל כתבו פונקציה רקורסיבית שמקבלת 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));
תרגיל כתבו פונקציה רקורסיבית שמחשבת את מספר הדרכים לעלות n מדרגות כאשר בכל צעד עולים מדרגה אחת או שתי מדרגות public static int takestairs(int n){ לעלות מדרגה אחת? רק אפשרות אחת 2 מדרגות? לעלות לדלג 2 לעלות "רגיל" או לעלות 3 מדרגות? לדלג 2 ושלישית, ראשונה ולדלג 2, לעלות "רגיל"...
פתרון public static int takestairs(int n){ if (n == 1){ return 1; if (n == 2){ return 2; return takestairs(n-1) + takestairs(n-2); הפתרון נראה מוכר?
)SUSU( בעיית Subset Sum בהנתן מערך של משקולות ומשקל נוסף, נרצה לבדוק האם ניתן להרכיב מהמשקולות משקל השווה למשקל הנתון. weights={1,7,9,3 Sum = 12 דוגמא לקלט: 9 במקרה זה הפונקציה תחזיר true ו- 3 ולקבל את הסכום 12. כי ניתן לחבר את המשקולות 17
אסטרטגיית פתרון נסתכל על האיבר הראשון SUSU weights[0] weights[1] weights[n-1], sum weights[0] יתווסף לסכום נותר לפתור בעיה קטנה יותר: האם ניתן להרכיב את הסכום sum-weights[0] מבין המשקולות שבתאים weights[1,,n-1] weights[0] לא יתווסף לסכום נותר לפתור בעיה קטנה יותר: האם ניתן להרכיב את הסכום sum מבין המשקולות שבתאים weights[1,,n-1] SUSU weights[1] weights[n-1] sum SUSU weights[1] weights[n-1] sum-weights[0]
אסטרטגיית פתרון המשך נעבור על כל האיברים במערך ונבחן אפשרויות בהן איבר נבחר או לא נבחר. קיימים שני מקרי בסיס:.1.2 הגענו לסכום הדרוש, או במילים אחרות - הסכום הנותר הינו אפס. הגענו לסוף המערך עברנו על כל האיברים ולא מצאנו צירוף של איברים שסכומם שווה לסכום הנדרש. 19
פתרון פתרון זה קל להציג כפונקציה רקורסיבית: 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); 20
פתרון )המשך( 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; 21