תרגול מס' 7: Memoization Quicksort תרגילים מתקדמים ברקורסיה

Slides:



Advertisements
Similar presentations
תרגול 8 Skip Lists Hash Tables. Skip Lists Definition: – A skip list is a probabilistic data structure where elements are kept sorted by key. – It allows.
Advertisements

מבוא למדעי המחשב לתעשייה וניהול
מבוא למדעי המחשב לתעשייה וניהול דוגמאות ותרגול נוסף במערך חד ממדי הרצאה 12.
מכונת מצבים תרגול מס' 4 Moshe Malka.
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
חורף - תשס " ג DBMS, Design1 שימור תלויות אינטואיציה : כל תלות פונקציונלית שהתקיימה בסכמה המקורית מתקיימת גם בסכמה המפורקת. מטרה : כאשר מעדכנים.
תכנות תרגול 6 שבוע : חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
מה החומר למבחן ? כל החומר שנלמד בהרצאות ובתרגולים. לגבי backtracking: לא תידרשו לממש אלגוריתם, אך כן להבין או להשלים מימוש נתון. אחת משאלות המבחן מבוססת.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
אוטומט מחסנית הפקולטה למדעי המחשב אוטומטים ושפות פורמליות ( ) תרגיל מספר 11.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
11 Introduction to Programming in C תרגול
מבוא למדעי המחשב תרגול 8 - מחרוזות שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
מבוא למדעי המחשב תרגול 4 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
עיבוד תמונות ואותות במחשב אלכסנדר ברנגולץ דואר אלקטרוני : שיטות קידוד שיטות קידוד אורך מלת קוד ואנטרופיה אורך מלת קוד ואנטרופיה קידוד.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
מבוא לשפת C תרגול 12: עוד רקורסיה
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
ערמות ; מבני נתונים 09 מבוסס על מצגות של ליאור שפירא, חיים קפלן, דני פלדמן וחברים.
תכנות תרגול 6 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מבוא למדעי המחשב תרגול 6 - מערכים שעת קבלה : יום שני 11:00-12:00 דוא " ל :
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
תזכורת : אלגברה ליניארית מסקנה קלט : וקטורים פלט : האם u תלוי ליניארית ב קלט : מערכת של n משואות לינאריות ב -m נעלמים. פלט : פתרון, או שאין כזה. אלגוריתם.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
יחס סדר חלקי.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
1 מבוא למדעי המחשב backtracking. 2 מוטיבציה בעיית n המלכות: נתון: לוח שחמט בגודל. המטרה: לסדר על הלוח n מלכות כך שאף אחת לא תאיים על השנייה. דוגמא: עבור.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
- אמיר רובינשטיין מיונים - Sorting משפט : חסם תחתון על מיון ( המבוסס על השוואות בלבד ) של n מפתחות הינו Ω(nlogn) במקרה הגרוע ובממוצע. ניתן לפעמים.
1 מבוא למדעי המחשב רקורסיה. 2 רקורסיה היא שיטה לפתרון בעיות המבוססת על העיקרון העומד ביסוד אינדוקציה מתמטית: אם ידועה הדרך לפתור בעיה עבור המקרים הבסיסיים.
תוכנה 1 תרגול מס ' 3 מערכים ומבני בקרה. 2 מערכים Array: A fixed-length data structure for storing multiple values of the same type Example: An array of.
מבוא למדעי המחשב הרצאה 11: תכנות רקורסיבי 4 כולל מיון רקורסיבי 1.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
מבוא למדעי המחשב הרצאה 9: תכנות רקורסיבי 2 1. חישוב עצרת: רקורסיית זנב public static int fact (int n){ return factacc(n,1); } public static int factacc.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 12. ספריות.
תרגול 8 Skip Lists Hash Tables. Skip Lists Definition: – A skip list is a probabilistic data structure where elements are kept sorted by key. – It allows.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
1 מבוא למדעי המחשב הרצאה 5: פונקציות. 2 מבוא לפונקציות חלוקה של אלגוריתם לתת משימות: משימה - פונקציה: דוגמאות מציאת המקסימלי מבין שני איברים האינדקס של.
1 נתבונן בפונקציה הבאה public static int min(int[] a,int n) { int min = a[0]; for (int i = 1; (i < n ) && (i < a.length) ; i++) if (min > a[i]) min = a[i];
תרגול חזרה לבוחן נמרוד מילוא.
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
Programming Arrays.
Tirgul 12 Trees 1.
Computer Architecture and Assembly Language
Formal Specifications for Complex Systems (236368) Tutorial #1
שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב
מבוא למדעי המחשב סיבוכיות.
רקורסיות קרן כליף.
מיונים וחיפושים קרן כליף.
רקורסיות קרן כליף.
SQL בסיסי – הגדרה אינדוקטיבית
תירגול 14: מבני נתונים דינאמיים
תרגול 5 רקורסיות.
Marina Kogan Sadetsky –
תרגול 11 NP complete.
Computer Programming Summer 2017
שאלות מבחינות קודמות יואב ציבין.
Introduction to Programming in C
תרגול Introduction to C - Fall Amir Menczel.
נושאים מחרוזות מיון (מיון בועות) רקורסיה
שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
מבוא לתכנות ב- Java תרגול 10 - רשימות מקושרות.
Presentation transcript:

תרגול מס' 7: Memoization Quicksort תרגילים מתקדמים ברקורסיה

סדרת פיבונצ'י לאונדרדו מפיזה הידוע בשמות ליאונדרו פיזאנו, ליאונרדו בונאצ'י, או בפשטות פיבונצ'י נחשב בעיני רבים לגדול המתמטיקאים של ימי הביניים. על שמו קרויה סדרת המספרים הבאה (בניגוד לדעה הרווחת הוא לא המציא אותה, רק השתמש בה): סדרה זו מופיעה בטבע בצורות מפתיעות: http://en.wikipedia.org/wiki/Fibonacci_number

חישוב המספר ה-n בסדרה: public class Fib { public static int fib(int n){ int ans; if (n==0) ans = 0; else if (n==1) ans = 1; else ans = fib(n-1)+fib(n-2); return ans; } public static void main(String[] args){ int n = 20; System.out.println("fib("+n+") = "+fib(n)); רקורסית זנב? לא!

Memoization (without ‘r’) ברישום הבא, מובא עץ הקריאות לפונקציה כאשר ניתן לראות כי ישנם מספר חישובים שמתבצעים יותר מפעם אחת (אלו המודגשים בצבע): fib(5) fib(3) fib(1) fib(2) fib(0) fib(4)

ניתן לחסוך את החישובים המיותרים ע"י שמירת תוצאות של חישובים שבוצעו: נשמור תוצאות ביניים ב lookup table-כך שחישוב יתבצע פעם אחת לכל היותר. לכל ערך שנרצה לחשב, נבדוק תחילה האם ערך זה חושב, כלומר, האם יש עבורו ערך מתאים ב lookup table. אם כן, נשתמש בערך זה. אחרת, נבצע את החישוב ונשמור את התוצאה בכניסה המתאימה בטבלה. הערכים נשמרים בטבלה לפי הקלט. כלומר, לכל קלט אפשרי יש כניסה מתאימה בטבלה.

דוגמא בכדי ליעל את fib נשתמש בטכניקת הmemoization לשמירת תוצאות החישובים שבוצעו. נראה תוכנית המחשבת את האיבר ה n-י בסדרת פיבונאצ'י, ומשתמשת בטכניקה זו לשמירת תוצאות של חישובים רקורסיביים. במקרה זה ה lookup table הינה מערך חד מימדי, כך שהתא בעל אינדקס i במערך, מכיל את הערך עבור fib(i). באם ערך זה עדיין לא חושב, יכיל תא זה את הערך 1-.

והפתרון: public class FibMemo{ פונקציה עוטפת public static int fib(int[] lookupTable, int n) { if (n==0) lookupTable[n]= 0; if (n==1) lookupTable[n]= 1; if (lookupTable[n]==-1)//EMPTY lookupTable[n] = fib (lookupTable,n-1) + fib(lookupTable,n-2); return lookupTable[n]; } פונקציה עוטפת public static int fib(int n) { int[] lookupTable = new int[n+1]; for (int i=0; i < lookupTable.length ; i=i+1){ lookupTable[i] = -1; //EMPTY } return fib(lookupTable, n);

Memoization כעת עץ הקריאות לפונקציה יראה כך: fib(5) fib(3) fib(1)

Divide-and-Conquer טכניקת ה Divide-and-Conquer מבוססת על רעיון דומה לפתרון רקורסיבי של בעיות: חלק את הבעיה המקורית לתתי בעיות קטנות (שניים או יותר) - Divide פתור כל תת בעיה – Conquer צרף את תתי הפתרונות לפתרון לבעיה המקורית.   ישנם אלגוריתמים רבים המתוכננים לפי עיקרון זה, עליהם נמנים האלגוריתמים הבאים: Mergesort (נלמד בהרצאות) Quicksort

תזכורת: חציון תזכורת: חציון הוא מדד למיקום המרכז של קבוצת נתונים מספריים. לדוגמא: החציון של קבוצת המספרים 1, 2, 22, 7, 19, 8, 16 הוא 8 מכיוון ש: 1, 2, 7, 8, 16, 19, 22

מיון מהיר (Quick Sort) חלוקת המערך לשני חלקים לפי ציר (pivot) שנבחר מחדש בכל שלב של הרקורסיה ומיון רקורסיבי של כל צד נרצה שהציר הנבחר יהיה הערכה (או ניחוש) של החציון במערך לצורך פישוט הבעיה בקוד שלנו נבחר את האיבר הראשון כציר.

מיון מהיר (Quicksort) - דוגמא 4 17 21 12 3 9 1 15 6 1 3 4 12 9 17 21 15 3 1 9 12 21 17 3 9 21 4 3 1 6 12 9 15 21 17 12

הבהרות אם נוכל להבטיח כי בכל שלב נבצע את השינוי על המערך עצמו ללא יצירת מערך חדש יתקיים שבסוף הריצה לאחר כל החלוקות המערך שלנו יהיה ממוין

מיון מהיר – הקוד public class QuickSort { //…. public static void quicksort(int[] arr, int start, int end){ if (start<end){ int i = partition(arr, start, end); quicksort(arr, start, i-1); quicksort(arr, i+1, end); } public static void quicksort(int[] arr){ quicksort(arr, 0, arr.length-1); }

מימוש פונקציית partition ברצוננו לממש פונקציה אשר מקבלת מערך ומשנה את המערך כך שקודם כל יופיעו כל המספרים הקטנים (או שווים) לאיבר הראשון לאחר מכן האיבר הראשון ולבסוף המספרים הגדולים מהאיבר הראשון. 4 17 21 12 3 9 1 15 6 קלט: 15 17 21 12 9 6 1 4 3 פלט:

מיון מהיר – partition public static int partition(int[] arr, int start, int end){ int pivot = arr[start]; int i = start; int j = end; while(i<j){ while(i<end && arr[i] <= pivot) //scan upwards i=i+1; while(arr[j] > pivot) //scan downwards j=j-1; if (i<j) swap(arr,i,j); } swap(arr,start,j); //put pivot in place return j;

דוגמאת ריצה של partition pivot pivot Swap! 4 17 21 12 3 9 1 15 6 15 17 21 12 9 6 1 4 3 15 17 21 12 9 3 1 4 6 15 17 21 12 3 9 1 4 6 start i i i j i i j j j j end j

מיון מהיר – פונקציות עזר public static void initRandomArray(int[] arr){ // shuffle the array arr int n = arr.length; for (int i = 0; i < n; i++) { arr[i] = (int) (Math.random() * 10 * n); } public static void printArray (int[] arr) { for (int i=0; i<arr.length; i=i+1) System.out.print (arr[i]+" "); System.out.println(); public static void swap(int[] arr, int i, int j){ // swap arr[i] and arr[j] int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;

מיון מהיר – הקוד (המשך) import java.util.Scanner; public class QuickSort { public static void main(String[] args){ Scanner sc = new Scanner(System.in); System.out.println("Enter number of elements to sort:"); int n = sc.nextInt(); int[] arr = new int[n]; // Initializes arr with random numbers // in [0..10*N) initRandomArray(arr); System.out.println("The input array:"); printArray(arr); quicksort(arr); System.out.println("The sorted array:"); } //…. continued

Quicksort Example Example: http://www.cise.ufl.edu/~ddd/cis3020/summer-97/lectures/lec17/sld001.htm www.cs.auckland.ac.nz/software/AlgAnim/Java/q_sort/tqs_new.html Video: www.youtube.com/watch?v=ywWBy6J5gz8 http://www.youtube.com/watch?v=o2dm4X-t8L0 http://www.youtube.com/watch?v=2HjspVV0jK4 http://www.youtube.com/watch?v=FSyr8o8jjwM

הדפסת המחרוזות באורך n בהינתן מספר מספר n 0 ≤, נרצה להחזיר מערך של 2n המחרוזות באורך n המורכבות מאפסים ואחדים. סדר המחרוזת הוא סדר המניה מאפס ל 2n-1 בבסיס 2. הפלט עבור n=0: {“”} הפלט עבור n=1: {“0”,”1”} הפלט n=2: {“00”,”01”,”10,”11”} הפלט עבור n=3: {“000”,”001”,”010”,”011”,“100”,”101”,”110”,”111”}

השלימו את הפונקציה public static String[] binaryNums(int n){ String[] answer; if (n==0){ answer = new String[1]; answer[0]=""; } else { // // Your code here } return answer; 22 22

הרעיון של הרקורסיה n=3 n=2 n=1 n=0 “”

רעיון של הרקורסיה n=3 n=2 “0” + “” “1” + “” n=1 1 n=0 “”

רעיון של הרקורסיה n=3 n=2 00 01 10 11 n=1 1 n=0 “”

רעיון של הרקורסיה n=3 000 001 010 011 100 101 110 111 n=2 11 01 00 10 n=1 1 n=0 “”

הקוד public static String[] binaryNums(int n) { String[] answer; if (n==0){ answer = new String[1]; answer[0]=""; } else { String[] prev = binaryNums(n-1); answer = new String[2*prev.length]; for (int i =0;i<prev.length; i = i+1) { answer[i]= "0" + prev[i]; answer[prev.length + i] = "1“+ prev[i]; } return answer; 27 27

הדפסת הפרמוטציות של מחרוזת פרמוטציה של מחרוזת מוגדרת כמחרוזת המכילה את אותן אותיות, ייתכן שבשינוי סדר. נניח בדוגמה זו שכל האותיות שונות זו מזו. למשל הפרמוטציות עבור המחרוזת bcd הם: “bcd" “bdc" “cbd“ “cdb” “dbc“ “dcb”

הרעיון של הרקורסיה i=0 i=1 ““, “a” + “b” + “c” +”d” d, “a” + “b” + “c” output: abcd i=0 cd, “a” + “b” cd, “a” + “b” i=0 bcd, “a” bcd, “a” נרוץ עם i מ0 עד גודל המחרוזת ועבור כל i נבחן את כל המחרזות האפשריות בהן התו הi הוא הראשון כך שבכל קריאה i הוא האינדקס של האות הבאה אותה מצרפים למחרוזת i=0 abcd,”” abcd,””

הרעיון של הרקורסיה i=1 ““, “a” + “b” + “c” +”d” d, “a” + “b” + “c” output: abcd i=0 i=1 cd, “a” + “b” cd, “a” + “b” i=0 bcd, “a” bcd, “a” i=0 abcd,”” abcd,””

הרעיון של הרקורסיה ““, “a” + “b” + “c” +”d” d, “a” + “b” + “c” output: i=1 i=2 cd, “a” + “b” cd, “a” + “b” “”, “a” + “b” + “d” + “c” i=0 c, “a” + “b” + “d” output: abdc bcd, “a” bcd, “a” i=0 abcd,”” abcd,””

הרעיון של הרקורסיה ““, “a” + “b” + “c” +”d” d, “a” + “b” + “c” output: i=1 cd, “a” + “b” cd, “a” + “b” i=1 “”, “a” + “b” + “d” + “c” i=1 c, “a” + “b” + “d” output: abdc bcd, “a” bcd, “a” i=0 abcd,”” abcd,”” bd, “a” + “c” bd, “a” + “c” d, “a” + “c” + “b” output: acbd “”, “a” + “c” + “b” + “d”

הרעיון של הרקורסיה . . . . . . ““, “a” + “b” + “c” +”d” d, “a” + “b” + “c” output: abcd cd, “a” + “b” cd, “a” + “b” “”, “a” + “b” + “d” + “c” i=3 c, “a” + “b” + “d” output: abdc bcd, “a” bcd, “a” abcd,”” abcd,”” bd, “a” + “c” bd, “a” + “c” d, “a” + “c” + “b” . . . bc, “a” + “d” output: acbd “”, “a” + “c” + “b” + “d” . . .

קוד הדפסת הפרמוטציות של מחרוזת public static void perms(String s){ // We call the method perm(s,"") which prints // the empty string followed by each permutation // of s the empty string. perms(s,""); }

קוד הדפסת הפרמוטציות של מחרוזת /** Function prints all the permutation of a string. * Note: assume the string is a set (no duplicate * chars) */ // Prints string acc followed by all permutations of // string s1 public static void perms(String s1, String acc){ if (s1.length()==0) System.out.println(acc); else for (int i=0; i<s1.length(); i=i+1) perms(delete(s1, i), acc +s1.charAt(i)); } אם יש זמן 35

פונק' עזר: delete // This function returns the string s with the i-th // character removed public static String delete(String s, int i){ // Assumes that i is a position in the string return s.substring(0,i) + s.substring(i+1,s.length()); } 36

הרכבת סכום נתון ממשקולות בהינתן מערך משקולות אי-שליליים ומשקל נוסף (משקל סכום), נרצה לבדוק האם ניתן להרכיב מהמשקולות משקל השווה למשקל הסכום הנתון. דוגמא לקלט: weights={1,7,9,3} Sum = 12 במקרה זה הפונקציה תחזיר true כי ניתן לחבר את המשקולות 9 ו 3 ולקבל את הסכום 12. דוגמא לקלט: weights={1,7,9,3} Sum = 15 במקרה זה הפונקציה תחזיר false כי לא ניתן לחבר משקולות לקבלת הסכום 15.

תיאור פתרון נתבונן באיבר הראשון במערך. ייתכן שהוא ייבחר לקבוצת המשקולות שתרכיב את הפתרון ויתכן שלא. אם הוא לא ייבחר (להיות כלול בסכום המהווה את משקל המטרה) – אזי נותר לפתור בעיה קטנה יותר והיא האם ניתן להרכיב את הסכום מבין המשקולות שנותרו במערך. אם הוא ייבחר – אזי נותר לפתור בעיה קטנה יותר והיא האם ניתן להרכיב את הסכום שנותר מבין המשקולות שנותרו במערך. וכנ"ל לגבי יתר האיברים בצורה רקורסיבית.

תיאור פתרון - המשך פתרון זה קל להציג כפונקציה רקורסיבית , boolean calcWeights(int[] weights, int i, int sum ) הפונקציה מחזירה ערך אמת האם ניתן להרכיב את הסכום מבין קבוצת המשקולות שבתת המערך. הפרמטרים: weights – מערך המשקולות sum – הסכום שיש להרכיב מהמשקולות i – פרמטר נוסף הנחוץ עבור הרקורסיה. i הוא אינדקס במערך weights ויסמן את האיבר הנוכחי במערך עליו מתבצעת הקריאה הרקורסיבית.

i=0 50 [10,20,30] i=1 40 [10,20,30] 50 [10,20,30] i=2 20 [10,20,30] 40 [10,20,30] 30 [10,20,30] 50 [10,20,30] i=3 -10 [10,20,30] 20 [10,20,30] 10 [10,20,30] 40 [10,20,30] [10,20,30] 30 [10,20,30] 20 [10,20,30] 50 [10,20,30]

קוד calcWeights הארגומנט i נחוץ עבור הרקורסיה – אך אינו באמת חלק מהקלט של הבעיה. בקריאה הראשונה ל calcWeights ערכו הוא 0. לכן נוסיף פונקצית מעטפת עם חתימה פשוטה יותר. // An envelope function, without i argument // A simpler signature public static boolean calcWeights(int[] weights, int sum) { return calcWeights(weights , 0, sum); }

(המשך) 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; }

דוגמה אחרונה הפונקציה void subsetsSum(int[] weights, int sum) מקבלת מערך weights של משקולות (ערכים שלמים חיוביים) ומשקל שלם sum חיובי ומדפיסה את כל תתי הקבוצות של איברי המערך weights שסכומם sum. דוגמא עבור weights={1,2,3,4,5} ו sum=10, הפונקציה תדפיס: 1 2 3 4 1 4 5 2 3 5

דוגמה אחרונה שאלה זו דומה מאוד לשאלת הרכבת סכום נתון ממשקולות. נסו להשלים את הפונקציות לבד. public static void subsetsSum(int[] weights, int sum){ subsetsSum(________השלימו את החסר___); } public static void subsetsSum( ){ השלימו את החסר }

דוגמה אחרונה: פתרון public static void subsetsSum(int[] weights, int sum){ subsetsSum(weights, sum,0,””); } public static void subsetsSum(int[] weights, int sum, int index, String acc){ if(sum == 0) System.out.println(acc); else if (sum > 0 && index < weights.length){ subsetsSum(weights,sum-weights[index], index+1,acc + weights[index] + ' '); subsetsSum(weights,sum,index+1,acc); } 45 45