תרגול חזרה לבוחן

Post on 31-Dec-2015

49 views 1 download

Tags:

description

תרגול חזרה לבוחן. נמרוד מילוא. Decimal system: Ten digits: 0,1,2,3,…,9. 3185. = 3*1000 + 1*100 + 8*10 + 5*1. = 3* 10^3 + 1* 10^2 + 8* 10^1 + 5* 10^0. Binary system: Two digits: 0,1. 10110. 1*(2^4) + 0*(2^3) + 1*(2^2) + 1*(2^1) + 0*(2^0). Byte and Bit. Binary to Decimal. - PowerPoint PPT Presentation

Transcript of תרגול חזרה לבוחן

תרגול חזרה לבוחן

נמרוד מילוא

3185

= 3*1000 + 1*100 + 8*10 + 5*1

= 3*10^3 + 1*10^2 + 8*10^1 + 5*10^0

Decimal system:

Ten digits: 0,1,2,3,…,9

10110

1*(2^4) + 0*(2^3) + 1*(2^2) + 1*(2^1) + 0*(2^0)

Binary system:

Two digits: 0,1

Byte and Bit

00001011

*

2^7

*

2^6

*

2^5

*

2^4

*

2^3

*

2^2

*

2^1

*

2^0

Binary to Decimal

00001011

0)*2^7(0)*2^6(0)*2^5(0)*2^4(1)*2^3(0)*2^2(1)*2^1(1)*2^0(

2^3 + 2^1 + 2^0 = 11

Decimal to Binary

251 [25%2=1]

12 [25/2=12]0 [12%2=0]

6 [12/2=6]0 [6%2=0]

3[ 6/2=2]1 [3%2=1]

1 [3/2=1]1 [1%2=1]

0 [1/2=0]

Right

Left

25 (decimal) = 11001 (binary)

7

פרימיטיבי. vs אינו פרימיטיבי משתנה שאינו

פרימיטיבימשתנה פרימיטיבי

מה נמצא הערך עצמו הכתובתבטבלת המשתנים

השמה הערך מועתק הכתובת מועתקת

השוואה בין כתובות

(==) השוואה בין ערכיםהשוואה

8

מבנה של פונקציהpublic static <return type> <func name> (<arg1_type> <arg1>, <arg2_type> <arg2>, …) {

>function body<

}

חתימה של פונקציה מורכבת משם הפונקציה ומרשימת •סוגי , טיפוסי הארגומנטים שהפונקציה מקבלת (מספר

טיפוסים וסדר)לכל שתי פונקציות בתכנית חתימה שונה• publicכגון )הערך המוחזר וכן מאפיינים נוספים של פונקציה •

) אינם נכללים בחתימה של הפונקציהstaticו- public static int foo(int num)}…{ √public static int foo(int num1, double num2)}…{ √public static int foo(double num)}…{ √public static double foo(int num)}…{ X

9

public class Sum{public static void main)String[] args({

int lastInd = 10;int sum = sumNums)lastInd(;

System.out.println)“The sum of numbers from 1 to “+ lastInd+ “ = “ + sum(;

System.out.println)“The sum of numbers from 1 to “+ 8 + “ = “ + sumNums)8((;

}

// returns the sum of numbers from 1 to endpublic static int sumNums)int end( {

int sum = 0;for)int i = 1; i <= end; i = i+1(

sum = sum + i;return sum;

}}

10

בזמן קריאה לפונקציה:השליטה של התכנית שומרת את המיקום הנוכחי •

שלה ועוברת לפונקציה.נפתחת סביבה (טבלת משתנים) חדשה שבה •

מוגדרים הפרמטרים של הפונקציה והמשתנים .שמוגדרים בתוך הפונקציה

(או סיום הפונקציה במקרה של returnההוראה •void סוגרת את הסביבה ומחזירה את השליטה (

למקום בו היינו לפני הקריאה לפונקציה

•Flow of previous func

main

sumNums(10)

11

public class Sum{public static void main)String[] args({

int lastInd = 10;int sum = sumNums)lastInd (;

System.out.println)“The sum of numbers from 1 to “+ lastInd + “ = “ + sum(;System.out.println)“The sum of numbers from 1 to “+ 8 + “ = “ + sumNums)8((;

}

// returns the sum of numbers from 1 to endpublic static int sumNums)int end( {

int sum = 0;for)int i = 1; i <= end; i = i+1(

sum = sum + i;return sum;

}}

endint10

sumint0lastIndint10

sumint55 sumint iint1

155

העברת משתנים לפונקציה

12

מועברים בעת קריאה לפונקציה בעלת Javaב-פרמטרים, הערכים הרשומים בטבלת המשתנים, בין אם

מדובר בערך ממש או בכתובת:

מה שיעבור - אם הפרמטר הוא מטיפוס פרימיטיבי,ולכן הפונקציה לא , לפונקציה הוא הערך של המשתנה.תוכל לשנות את המשתנה המקורי

- אם הפרמטר הוא מטיפוס שאינו פרימיטיבי, כלומר מכיל מצביע לאובייקט (כגון מערך), אז הפונקציה

מקבלת את הכתובת, ויכולה לשנות את האובייקט בזיכרון.

13

דוגמא להעברת פרמטרים מטיפוס פרימיטיבי:

public static void main(String[] args){

int x=8;

System.out.println(x);

add5(x);

System.out.println (x);

}

public static void add5(int x){

x = x+5;

System.out.println (x);

}

14

מה היינו עושים?xאם היינו רוצים לשנות את הערך של xכך שתחזיר ערך ואותו להכניס ל add5 היינו צריכים לשנות את

:

public static void main(String[] args){

int x=8;

System.out.println(x);

x=add5(x);

System.out.println(x);

}

public static int add5(int x) {

x = x+5;

System.out.println(x);

return x;

}

15

public static void main(String[] arg){int [] x={1,2,3};printArray(x);add5(x);printArray(x);

}

public static void add5(int[] y) {for (int i=0 ; i<y.length ;i=i+1)

y[i] = y[i]+5;printArray (y);

}

דוגמא להעברת פרמטרים מטיפוס לא פרימיטיבי:

/*/* outputoutput1 2 31 2 36 7 86 7 86 7 86 7 8*/*/

123

מחרוזותהקדמה

) היא מחלקה המייצגת טקסט (רצף של תווים). Stringמחרוזת (

ונגמר באורך 0מיספור אינדקס התווים במחרוזת מתחיל מ

.1המחרוזת פחות

String "abcd"

Index 0123

מבוא למדעי המחשב, בן גוריון תשע"א16

מחרוזותפעולות על מחרוזות:

הגדרה ואתחול•

String s1;

String s2 = "abcd";

String s3 = null;

String s4 = "";

String s5 = new String)(;

מבוא למדעי המחשב, בן גוריון תשע"א17

מחרוזות

אורך•

s2.length)(4

s3.length)(

NullPointerException

s4.length)(0

18

String s2 = "abcd";

String s3 = null;

String s4 = "";

מבוא למדעי המחשב, בן גוריון תשע"א

מחרוזות

תו במיקום (אינדקס) מסוים•

s2.charAt)0(

s2.charAt)1(

s2.charAt)5(

19

String s2 = "abcd";

'a'

'b'

StringIndexOutOfBoundsException

:String index out of range

מבוא למדעי המחשב, בן גוריון תשע"א

מחרוזות

).j (לא כולל את j ועד אינדקס i החל מאינדקס תת-מחרוזת•

s2.substring)1,3( "bc"

s2.substring)1( "bcd"

).false או true בין תוכן שתי מחרוזות. התוצאה בוליאנית (השוואה•

s2.equals)s4(

+ שרשור•

s2+"efg" יוצר מחרוזת חדשה "abcdefg" המחרוזת .s2.לא משתנה

20

String s2 = "abcd";

מבוא למדעי המחשב, בן גוריון תשע"א

מחרוזות

– מחרוזת עם סדר תווים הפוך 1דוגמה

המקבלת מחרוזת reverseלפנינו פונקציה

ומחזירה מחרוזת אחרת שבה התווים של

reverse בסדר (מיקום) הפוך. הפונקציה

על המחרוזת reverseהראשית מפעילה את

"Hello") ומדפיסה את התוצאה olleH.(

מבוא למדעי המחשב, בן גוריון תשע"א21

public class StringReverser {

public static String reverse) String data ( {

String rev = new String)(;

for ) int j=data.length)(-1; j>=0; j=j-1 (

rev = rev + data.charAt)j(;

return rev;

}

public static void main ) String[] args ( {

System.out.println) reverse) "Hello" ( (;

}

}

מבוא למדעי המחשב, בן גוריון תשע"א22

מחרוזות – חיפוש של תת-מחרוזת במחרוזת2דוגמה

sub ו- str המקבלת שתי מחרוזת isSubstringלפנינו פונקציה

כתת מחרוזת. הפונקציה str מופיעה בתוך subובודקת האם

מחזירה תשובה בוליאנית.

באינדקס " abcd" מופיעה כתת-מחרוזת במחרוזת "bc"למשל, המחרוזת

1.

String "abcd"

Index 0123

בעלות אורך זהה."abcd" לתתי מחרוזות של "bc"נשווה את

מבוא למדעי המחשב, בן גוריון תשע"א23

public static boolean isSubstring)String str,String sub({

boolean found = false;

int lastInd = str.length)(- sub.length)(;

for ) int i=0; i<=lastInd && !found; i=i+1( {

String strSub = str.substring)i, i+sub.length)((;

if )strSub.equals)sub((

found = true;

}

return found;

}

מבוא למדעי המחשב, בן גוריון תשע"א24

ASCIIטבלת

מחרוזות– צופן קיסר 3דוגמה

טקסט ) הוא אלגוריתם הצפנה, המקבל Cipherצופן (. טקסט מוצפן - ומחזיר מפתח וקריא

צופן קיסר מבוסס על רעיון החלפת האותיות של •הטקסט הקריא לשם יצירתו של הטקסט המוצפן:

האלפבית המשמש להצפנה מוסט מעגלית במספר קבוע של 'מקומות' מן האלפבית הרגיל.

)= מספר מקומות ההסטה keyהמפתח (•

לפי עדויות היסטוריות יוליוס קיסר עשה בשיטה זו •שימוש נרחב.

מבוא למדעי המחשב, בן גוריון תשע"א26

מחרוזות

BABY מקומות המילה3למשל, בהזזת של תתורגם...

.EDEBלמילה

מבוא למדעי המחשב, בן גוריון תשע"א27

public static String encrypt)String str, int key( {

String ans = "";

final int NUM_OF_LETTERS_IN_ALPHABET = 26;

for)int i = 0; i < str.length)(; i=i+1( {

int c = str.charAt)i(;

if )'A'<=c & c<='Z'( {

c = c - 'A';

c = ))c + key( % NUM_OF_LETTERS_IN_ALPHABET(+'A';

}

else if )'a'<=c & c<='z'({

c = c - 'a';

c = ))c + key( % NUM_OF_LETTERS_IN_ALPHABET(+'a';

}

ans = ans + )char(c;

}

return ans;

}

מבוא למדעי המחשב, בן גוריון תשע"א28

מחרוזות:כמה הערות

; )int c = str.charAt)iבפקודה 1.

.int ל charמתרחשת המרת טיפוס אוטומאטית מ

. 'c - 'A ו- A'<=c' כנ"ל בביטויים כמו

; ans = ans + )char(cבפקודה 2.

. פעולה זו נחוצה מכיוון char ל intיש המרת טיפוס מפורשת מ

.int (65) ולא char ('A')שנרצה לשרשר למחרוזת התוצאה ערך

, ASCIIהערכים המספריים של כל תו מסוכמים בטבלה (טבלת 3.

). אין כלל צורך לזכור את הטבלה בע"פ.UNICODEתקן

מבוא למדעי המחשב, בן גוריון תשע"א29

מחרוזותpublic static void main)String[] args( {

String str = "BEN GURION UNIVERSITY";

int key = 3;

String encrypted = encrypt)str, key(;

System.out.println)encrypted(;// "EHQ JXULRQ XQLYHUVLWB"

String decrypted = decrypt)encrypted, key(;

System.out.println)decrypted(;// "BEN GURION UNIVERSITY"

}

: מהי פעולת פענוחשאלה (decrypt) של צופן קיסר?

: בדומה להצפנה, מלבד חיסור של מפתח ההזזה במקום חיבורותשובה .

מבוא למדעי המחשב, בן גוריון תשע"א30

מחרוזות

פריצת צופן קיסרבהינתן טקסט מוצפן כיצד ניתן לגלות את הטקסט •

הקריא מבלי לדעת את המפתח?ניתן לנחש את המפתח בו הוצפן הטקסט •

באמצעות סטטיסטיקה על השכיחויות של אותיות האלף בית האנגלי בטקסט כלשהו. האות השכיחה

.12%, שכיחותה Eביותר בטקסט באנגלית היא הבא תכתוב תוכנית המוצאת את האות quizב –•

השכיחה ביותר בטקסט נתון. סביר להניח שאות זו וככה ניתן לחשב בכמה Eהיא הקידוד של האות

הזזנו את האותיות.

מבוא למדעי המחשב, בן גוריון תשע"א31

מיונים

) - הגדרת הבעיה: בהינתן array sortמיון מערך ( מספרים שלמים חשב מערך ממוין n של Aמערך

של אותם מספרים. 

למשל:Input: 7 , 18, 28 , 4, 10Output: 4, 7, 10 , 18 , 28

ישנם שיטות מיון רבות, כמו: מיון בחירה, מיון הכנסה ומיון בועות.

מבוא למדעי המחשב, בן גוריון תשע"א32

מיונים

)Bubble Sort(מיון בועות  

תיאור השיטה:תוך כדי המיון, החלק הימני של המערך כבר ממוין

("מעל פני הים") והחלק השמאלי של המערך אינו ממוין ("מתחת לפני הים").

בכל סבב, "בועה" מבעבעת עד שהיא מגיעה לפני הים. הבועה "סוחבת" איתה ערכים גדולים:

בביעבוע הבועה, בכל שני תאים סמוכים בהן עוברת הבועה, מוחלפים הערכים אם הם לא

בסדר המיון.

מבוא למדעי המחשב, בן גוריון תשע"א33

מיונים

34

וכן הלאה עד אשר המערך כולו מעל פני הים.

 http://www.youtube.com/watch?v=t_xkgcakREw&feature=related

מבוא למדעי המחשב, בן גוריון תשע"א

public static void bubbleSort)int[] array({

int tmp;

/* @pre: bbl=0 */

for )int bbl=0; bbl<array.length-1; bbl=bbl+1( {

/* @inv: array[array.length- bbl.. array.length-1] is sorted

* and all numbers array[array.length-bbl.. array.length-1]

* are bigger than the numbers array[0 .. array.length-bbl-1] */

for )int index=0; index < array.length-1; index=index+1( {

if )array[index] > array[index+1]( {

tmp = array[index];

array[index] = array[index+1];

array[index+1] = tmp;

}

}

}

/* @post: array is sorted */

} מבוא למדעי המחשב, בן גוריון תשע"א35

מיונים

(array[index] > array[index+1]): כמה השוואות מתבצעות? שאלה

השוואות. הלולאה n: הלולאה הפנימית מבצעת תשובה פעמים. nהחיצונית מתבצעת

השוואות. n2 סה"כ  

: האם כל ההשואות נחוצות? שאלה: לא. תשובה

אם המערך כבר ממוין אין צורך להמשיך בלולאה. (לא •צריך לבעבע עוד בועה)

השוואות הנעשות בחלק הממויין מיותרות. (פני הים •יורדים, ויש להשוות איברים רק מתחת לפני הים)

מבוא למדעי המחשב, בן גוריון תשע"א36

public static void bubbleSort)int[] array({

boolean isSorted = false;

int tmp;

for )int bbl=0; !isSorted && bbl<array.length-1; bbl=bbl+1({

isSorted = true;

for )int index=0; index<array.length-1-bbl; index=index+1({

if )array[index] > array[index+1]( {

tmp = array[index];

array[index] = array[index+1];

array[index+1] = tmp;

isSorted = false;

}

}

}

}

מבוא למדעי המחשב, בן גוריון תשע"א37

)Quick Sortמיון מהיר () שנבחר pivotחלוקת המערך לשני חלקים לפי ציר (

מחדש בכל שלב של הרקורסיה ומיון רקורסיבי של כל צד

הציר שנבחר הינו הערכה (ניחוש) של החציון של המספרים במערך

תזכורת: חציון הוא מדד למיקום המרכז של קבוצת נתונים מספריים. לדוגמא: החציון של קבוצת

8 הוא 16, 8, 19, 7, 22, 2, 1המספרים

נבחר בקוד שלנו את האיבר הראשון כציר.

38

- דוגמא )Quicksortמיון מהיר (

6151931221174

431 152117912

13 129 1721

9

134 6 912 15 1721

213

39

מיון מהיר – הקוד

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:"(;printArray)arr(;

} //…. continued 40

מיון מהיר – הקוד (המשך)

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;

}

public static void initRandomArray)int[] arr({// shuffle the array arrint 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)(;} 41

מיון מהיר – הקוד (המשך)

public static void quicksort)int[] arr({quicksort)arr, 0, arr.length-1(;

}

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(;

}}

42

מיון מהיר – הקוד (המשך)

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(i=i+1;

while)arr[j] > pivot( j=j-1;

if )i<j( swap)arr,i,j(;

}

swap)arr,start,j(;return j;

}

43

הדפסת הפרמוטציות של מחרוזת

פרמוטציה של מחרוזת מוגדרת כמחרוזת המכילה את אותן •אותיות, ייתכן שבשינוי סדר. נניח בדוגמה זו שכל האותיות

שונות זו מזו.

: הםbcdהמחרוזת למשל הפרמוטציות עבור •–“bcd "–“bdc "–“cbd“–“cdb”–“dbc“–“dcb”

44

הרעיון של הרקורסיה

45

abcd,””

bcd, “a”

abcd,””

bcd, “a”

cd, “a” + “b”cd, “a” + “b”

abcdd, “a” + “b” + “c”

““, “a” + “b” + “c” +”d”

output:

i=0

i=0

i=0

i=0i=1i האינדקס =

שלפיו מחלקים את

המחרוזת

הרעיון של הרקורסיה

46

abcd,””

bcd, “a”

abcd,””

bcd, “a”

cd, “a” + “b”cd, “a” + “b”

abcdd, “a” + “b” + “c”

““, “a” + “b” + “c” +”d”

output:

i=0

i=0

i=0

i=1

i=1

הרעיון של הרקורסיה

47

abcd,””

bcd, “a”

cd, “a” + “b”

d, “a” + “b” + “c”

abcd,””

bcd, “a”

cd, “a” + “b”

““, “a” + “b” + “c” +”d”

abcd

c, “a” + “b” + “d”

“”, “a” + “b” + “d” + “c”

abdcoutput:

output:

i=0

i=0

i=1i=2

הרעיון של הרקורסיה

48

abcd,””

bcd, “a”

cd, “a” + “b”

d, “a” + “b” + “c”

abcd,””

bcd, “a”

cd, “a” + “b”

““, “a” + “b” + “c” +”d”

abcd

c, “a” + “b” + “d”

“”, “a” + “b” + “d” + “c”

abdc

bd, “a” + “c”bd, “a” + “c”

d, “a” + “c” + “b”

“”, “a” + “c” + “b” + “d”

acbd

output:

output:

output:

i=0

i=1

i=1

i=1

הרעיון של הרקורסיה

abcd,””

bcd, “a”

cd, “a” + “b”

d, “a” + “b” + “c”

abcd,””

bcd, “a”

cd, “a” + “b”

““, “a” + “b” + “c” +”d”

abcd

c, “a” + “b” + “d”

“”, “a” + “b” + “d” + “c”

abdc

bd, “a” + “c”bd, “a” + “c”

d, “a” + “c” + “b”

“”, “a” + “c” + “b” + “d”

acbd

output:

output:

output:bc, “a” + “d”

. . .

. . .

i=3

49

: הדפסת 3קוד של דוגמה הפרמוטציות של מחרוזת

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,"");}

50

/** 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((;}

: הדפסת 3קוד של דוגמה הפרמוטציות של מחרוזת

51

deleteפונק' עזר:

// This function returns the string s with the i-th // character removedpublic static String delete)String s, int i({

// Assumes that i is a position in the stringreturn s.substring)0,i( +

s.substring)i+1,s.length)((;}

52

- 4דוגמה הרכבת סכום נתון ממשקולות

בהינתן מערך משקולות אי-שליליים ומשקל נוסף (משקל סכום), נרצה לבדוק האם ניתן להרכיב מהמשקולות

משקל השווה למשקל הסכום הנתון.

דוגמא לקלט:•weights=}1,7,9,3{ Sum = 12

כי ניתן לחבר את trueבמקרה זה הפונקציה תחזיר .12 ולקבל את הסכום 3 ו 9המשקולות

דוגמא לקלט: •weights=}1,7,9,3{ Sum = 15

כי לא ניתן לחבר falseבמקרה זה הפונקציה תחזיר .15משקולות לקבלת הסכום

53

תיאור פתרון נתבונן באיבר הראשון במערך. ייתכן שהוא ייבחר

לקבוצת המשקולות שתרכיב את הפתרון ויתכן שלא. אם הוא לא ייבחר )להיות כלול בסכום המהווה את

משקל המטרה( – אזי נותר לפתור בעיה קטנה יותר והיא האם ניתן להרכיב את הסכום מבין המשקולות

שנותרו במערך. אם הוא ייבחר – אזי נותר לפתור בעיה קטנה יותר

והיא האם ניתן להרכיב את הסכום שנותר מבין .המשקולות שנותרו במערך

.וכנ"ל לגבי יתר האיברים בצורה רקורסיבית

54

תיאור פתרון - המשך

פתרון זה קל להציג כפונקציה רקורסיבית ,•boolean calcWeights(int[] weights, int i, int sum )

הפונקציה מחזירה ערך אמת האם ניתן להרכיב את •הסכום מבין קבוצת המשקולות שבתת המערך.

הפרמטרים: •weightsמערך המשקולות – sumהסכום שיש להרכיב מהמשקולות – i .פרמטר נוסף הנחוץ עבור הרקורסיה – i הוא אינדקס

ויסמן את האיבר הנוכחי במערך עליו weightsבמערך מתבצעת הקריאה הרקורסיבית.

55

50:

50: [20,30]

40: [20,30]

40: [30]

40: []

10: []

20: [30]

20: []

-10[]

i=1

i=3

[10,20,30]

i=0

i=2

56

50:

50: [20,30]

i=1

30: [30]

0: []

50: [30]

i=350: []

i=2

20: []

30: []

[10,20,30]

40: [20,30]

i=0

האם צריך לחשבענף ?ימני

57

calcWeights: 4קוד דוגמה

הארגומנט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) ;

}

58

פתרון (המשך)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;

}

59