אוניברסיטת חיפה החוג למדעי המחשב מרצה: שולי וינטנר מתרגלים: נעמה טוויטו, מחמוד שריף מבוא למדעי המחשב סמסטר א' תשע"ב בחינת סיום, מועד א', 6.2.2012 הנחיות: 1. משך הבחינה: 120 דקות. 2. היציאה מהכיתה במהלך הבחינה אסורה. 3. אין להשתמש בכל חומר עזר. 4. ודאו כי בטופס שבידיכם 10 עמודים. עליכם לכתוב את התשובות על הטופס ולהגיש את כל הטופס ואת הטופס בלבד. 5. קראו היטב כל שאלה וודאו שאתם מבינים אותה לפני שתתחילו לענות עליה. אם יש שאלות, פנו למרצה או למתרגלים. 6. כתבו בכתב יד ברור וקריא. ניתן לכתוב בעיפרון. 7. ניתן לכתוב הערות בעברית, גם בגוף פונקציות C. 8. אם לא נכתב אחרת, כאשר אתם מתבקשים להגדיר פונקציה, עליכם להגדיר פונקציה אחת בדיוק. אין להגדיר או להשתמש בפונקציות נוספות. 9. אם לא נכתב אחרת, מותר להשתמש בפונקציות וקבועים שנלמדו בכיתה מתוך הספריות stdio ו- stdlib בלבד.לא ניתן להשתמש בפונקציות שלא נלמדו בכיתה. 10. אם מוגדרות דרישות סיבוכיות, על הפתרון שלכם לעמוד בהן. פתרון שלא יעמוד בדרישות הסיבוכיות לא יזכה בנקודות כלל. בהצלחה! שאלה 1 2 3 ציון /30 /30 /40 סה"כ 1
שאלה (30%) 1 נתונה הגדרה של שתי פונקציות (הניחו ש- n אינו שלילי): double Mystery1(double x, int n) int i; double temp=1.; for(i=1;i<=n;i++) temp *= Mystery2(x,i); temp *= temp; for(i=0;i<n;i++) temp /= Mystery2(x,n); return temp; double Mystery2(double x, int n) if(n==0) return 1; else return x*mystery2(x,n-1); א. (10%) הסבירו בקצרה ובדייקנות מה מחשבת Mystery1(x,n) כפונקציה של x ו- n. שימו לב שטעות בסעיף זה תשרה טעות נגררת בשאר הבעיה: עליכם לדייק כאן! ב. (5%) מהי הסיבוכיות (הכוללת) של,Mystery1 כפונקציה של n? 2
ג. (15%) הגדירו פונקציה שקולה ל- Mystery1 שהסיבוכיות שלה (n.o(log לא ניתן להשתמש בפונקציות חיצוניות ולא ניתן להגדיר יותר מפונקציה אחת בבעיה זו. אם אינכם מוצאים פתרון, הגדירו פונקציה בסיבוכיות,O(n) עבור חצי מהנקודות. double f (double x, int n) 3
שאלה (30%) 2 נתונה ההגדרה הבאה של צמתים בעץ בינארי: typedef struct tnode *Tnodep; typedef struct tnode int contents; /* contents of the node */ Tnodep left, right; /* left and right children */ Tnode; הגדירו פונקציה שחתימתה: int same (Tnodep root1, Tnodep root2); הפונקציה מקבלת שני מצביעים לעצים בינארי, ומחזירה 1 אם העצים זהים, 0 אחרת. שני עצים הם זהים אם המבנה שלהם זהה, ואם תוכן הצמתים באותו מקום במבנה זהה אף הוא. למשל, העצים הבאים אינם זהים, אבל תתי העצים של שניהם, שהשורש שלהם הוא 2, זהים: 7 7 / \ / \ 3 2 3 2 / / \ / / \ 5 1 3 9 1 3 6 6 הבהרות: בעץ בינארי לכל צומת לכל היותר שני בנים (אך אולי פחות). 1. אסור לפונקציה להרוס את מבני העצים שהיא מקבלת כקלט. 2. לא ניתן להשתמש בפונקציה במשתנים חיצוניים או סטטיים. 3. לא ניתן להגדיר יותר מפונקציה אחת. 4. 4
int same (Tnodep root1, Tnodep root2) 5
שאלה (40%) 3 מערך בגודל n של שלמים הוא דליל אם לכל היותר SIZE מהתאים בו מכילים ערכים שאינם 0. בשאלה זו הניחו ש- SIZE הוא קבוע, למשל 100. כרגיל, נניח ש- n גדול, ובפרט גדול בהרבה מ- SIZE. בשאלה זו עליכם למצוא ייצוג חסכוני בזיכרון עבור מערך דליל. 1 0 2 0 3 0 4 0 0 0 5 0 0 0 0 1 2 3 4 0 0 0 0 0 0 0 0 1 0 0 0 לדוגמה, אם SIZE=5 אזי המערכים הבאים דלילים: 1.(5%) הגדירו פונקציה שחתימתה int is_sparse(int a[], int n); המקבלת מערך a ואת גודלו n ומחזירה 1 אם המערך דליל, 0 אחרת. int is_sparse(int a[], int n) 6
2. (10%) הציעו מבנה נתונים חסכוני במקום כדי לאחסן בו את האברים של מערך דליל. הפיתרון צריך לאפשר המרה של מערך דליל למבנה שהצעתם ובחזרה בסיבוכיות.O(n) כמו כן, הזיכרון הנדרש כדי לאחסן מערך דליל בגודל n צריך להיות ליניארי ב- SIZE, ולא תלוי ב-.n תארו במילים את המבנה המוצע: הגדירו טיפוס נתונים בשם SparseArray המממש את הפתרון המוצע: 7
3. (10%) הגדירו פונקציה הממירה מערך דליל למבנה הנתונים שהצעתם. הפונקציה מקבלת מערך דליל a ואת אורכו n וכן מצביע s למבנה מטיפוס,SparseArray ומחזירה מספר שלם, שהוא גודל המבנה s. כמובן, על הפונקציה לייצג את המערך a במבנה s. int array_to_sparse (int a[], int n, SparseArray *s); 4. (10%) הגדירו פונקציה הממירה את מבנה הנתונים שהצעתם למערך רגיל. הפונקציה מקבלת מצביע s למבנה שהצעתם, ומספר שלם המציין את גודל המבנה. כמו כן היא מקבלת כתובת של מערך שבו יש לאחסן את נתוני המבנה. היא מחזירה מספר שלם המציין את גודל המערך. int sparse_to_array (SparseArray *s, int k, int a[]); על כל אחת משתי הפונקציות לעבוד בסיבוכיות.O(n) כמו כן, אם a הוא מערך בגודל n אזי ביצוע שתי ההוראות הבאות: k = array_to_sparse(a,n,&s); n = sparse_to_array(&s,k,a); לא ישנה כלל את התוכן של a ואת הערך של n. 8
int array_to_sparse (int a[], int n, SparseArray *s) 9
int sparse_to_array (SparseArray *s, int k, int a[]) 10