אוניברסיטת בן גוריון בנגב מספר נבחן : במבחן זה 6 שאלות המאפשרות לצבור יותר מ- 100 נקודות אבל הציון המרבי במבחן 100 רשמו תשובותיכם בדפי התשובות בלבד מחברת הטיוטה לא תימסר לבדיקה בסיום המבחן נאסוף רק את דפי התשובות מותר להגדיר פונקציות עזר בכל השאלות, אלא אם נאמר אחרת. כתבו קוד קריא והקפידו על אינדנטציה והערות (בעברית). ב ה צ ל ח ה! תאריך המבחן: כ"ג אדר תשע"ג 5.3.13 שמות המורים: ציון סיקסיק, אלכסנדר צ'ורקין מבחן ב: מס' הקורס : מיועד לתלמידי : תכנות ב- Cא ' 202-1-9011 הנדסה שנה תשע"ג סמ' א' מועד ב' משך הבחינה : 3 שעות חומר עזר : דף פוליו אחד לא מודפס ולא מצולם. אין להשתמש במחשבון. שאלה (15 1 נקודות) הגדרה: עץ בינארי הינו ערימת מקסימום, אם הוא עץ ריק או אם הערך בכל צומת גדול מכל שאר האיברים בתת העץ המושרש בו (שהוא שורשו). דוגמא: העץ הימני הינו ערימת מקסימום. העץ השמאלי אינו ערימת מקסימום שכן תת-העץ שבשורשו הערך 3 מכיל את הערך 10 שגדול ממנו. לעומת זאת, תת-העץ המוקף בעיגול הינו ערימת מקסימום בת 4 איברים. typedef struct node { int value; struct node *left, *right; node; נתונה ההגדרה הבאה: - 1 -
סעיף א'. (7 נקודות) הפונקציה root) int ismaxheap(node* מקבלת מצביע לשורש של עץ ומחזירה 1 אם העץ הינו ערימת מקסימום, אחרת מחזירה 0. int ismaxheap(node* root){ int ans =?? 1?? ; if (?? 2?? ) return 1; if (root->left) ans =?? 3?? &&?? 4?? ; if (root->right) השלימו את הקטעים החסרים (המסומנים ב-?? N?? ( בקוד הבא: ans =?? 5?? &&?? 6?? &&?? 7??; return ans; סעיף ב'. (8 נקודות) הפונקציה root) int maxheapsize(node* מקבלת מצביע לשורש של עץ ומחזירה את מספר האיברים בתת העץ הגדול ביותר המהווה ערימת מקסימום. למשל, עבור העץ שבציור הימני הפונקציה תחזיר 8, ועבור העץ שבציור השמאלי הפונקציה תחזיר 4. int maxheapsize(node* root){ int numl, numr; if (!root) return 0; if (?? 1?? ) return?? 2?? ; numl =?? 3?? ;?? 4?? ; if (?? 5?? ) return?? 6?? ; return?? 7?? ; השלימו את הקטעים החסרים (המסומנים ב-?? N?? ( בקוד הבא: ניתן להשתמש (מבלי לממש) בפונקציה root) int numofelementsintree(node* מצביע לשורש העץ המחזירה את מספר האיברים בעץ. ניתן להשתמש בפונקציה מסעיף א' גם אם לא עניתם על סעיף זה. המקבלת הערות: - 2 -
#include <stdio.h> #include <string.h> */ סימן רווח /* ' ' SPACE #define שאלה ) 2 15 נקודות) נתונה התכנית הבאה: void what1 (char* str) { int i, tmp, len; len = strlen(str); for (i=0; i<len/2; ++i) { tmp = str[i]; str[i] = str[len-1-i]; str[len-1-i] = tmp; void what2 (char* s1, char* s2) { if(!*s2) return; if(*s2 == SPACE) { *s2 = '\0'; what1(s1); *s2 = SPACE; what2(s2+1, s2+1); what1(s1); what2(s1, s2+1); void main () { char str[ ][100] = {"one two", "one two three", "one two three four", "one two three four five six seven"; int i; for(i=0; i<4; i++){ what2(str[i], str[i]); puts(str[i]); סעיף א'. (8 נקודות) מה הפלט של התכנית הנ"ל? סעיף ב'. (7 נקודות) הסבר בקצרה ובמדויק מה יעודה של הקריאה str) what2(str, עבור srt מצביע למחרוזת שמכילה רצף של מילים עם רווח אחד בין מילה למילה וללא רווחים בהתחלה ובסוף של המחרוזת. - 3 -
typedef struct listnode{ int data; struct listnode *next; listnode; שאלה (15 3 נקודות) נתונות ההגדרות הבאות: typedef struct treenode{ int data; struct treenode *right, *left; treenode; הפונקציה *lst) treenode *list2searchtree(listnode מקבלת מצביע לראש רשימה מקושרת ויוצרת עץ חיפוש מהרשימה, הפונקציה מחזירה מצביע לעץ החיפוש אותו יצרה. תזכורת: עץ חיפוש בינארי מקיים עבור כל צומת תת העץ השמאלי שלו מכיל ערכים הנמוכים או שוים לערך הצומת, ואילו תת העץ הימני מכיל ערכים הגדולים מערך הצומת. treenode *list2searchtree(listnode *lst){ treenode *tree = NULL, *p, *q; השלימו את הקטעים החסרים (המסומנים ב-?? N?? ( בקוד הבא: while( lst ){ p = (treenode *)malloc(sizeof(treenode)); p->data =?? 1?? ; p->right = p->left = NULL; if(tree == NULL){ tree =?? 2?? ; p =?? 3?? ; q = tree; while( p ){ if(q->data < p->data) if(q->right == NULL){ q->right =?? 4?? ; p=null; q =?? 5?? ; if(q->left==null){ q->left =?? 6?? ; p=null; q =?? 7?? ; lst =?? 8?? ; return?? 9?? ; - 4 -
שאלה (20 4 נקודות) פועל מסוגל לטפס בסולם כך שבכל פעם הוא מתקדם שלב אחד או שני שלבים או שלושה שלבים. סעיף א'. (14 נקודות) כתובו פונקציה רקורסיבית (n int ladderrec(int שמקבלת את מספר השלבים הכולל בסולם ומחזירה את מספר המסלולים האפשריים בהם הפועל יכול לעלות בסולם. סעיף ב'. (6 נקודות) כתובו פונקציה איטרטיבית (n int ladder(int שמקבלת את מספר השלבים הכולל בסולם ומחזירה את מספר המסלולים האפשריים בהם הפועל יכול לעלות בסולם. (כמו א' רק איטרטיבי שימו לב למגבלות) הגבלות: בסעיף א' אין להשתמש בלולאות כלל. בסעיף ב' - אין להשתמש ביותר מלולאה אחת וכמובן לא ברקורסיה. בשני הסעיפים - אין להשתמש בפונקצית עזר או בפונקצית ספריה. דוגמא (רלוונטית לשני הסעיפים): בסולם עם 7 שלבים, אחד המסלולים האפשריים 3. 1 3 עוד מסלול אפשרי הוא 2 2 3 וכמובן שיש עוד מסלולים אפשריים (שימו לב, עליכם להחזיר את מספר המסלולים האפשריים ולא את המסלולים עצמם). - 5 -
שאלה ) 5 20 נקודות) תזכורת: סדרה הנדסית היא סדרה של מספרים, כך שהמנה של כל שני איברים עוקבים (או היחס בין כל שני איברים סמוכים) היא קבועה. במלים אחרות, ניתן לחשב כל איבר על ידי הכפלת האיבר הקודם לו במנת הסדרה. typedef struct node { int val; struct node *next; node; נתונה ההגדרה הבאה : כתבו פונקציה list) void GeometricProgression(node * המקבלת מצביע לראש רשימה המכילה תתי סדרות הנדסיות באורך 2 לפחות. הפונקציה תשנה את הרשימה כך שבמקום כל תת סדרה הנדסית יהיו 3 חוליות שיכילו את הערכים הבאים: האיבר הראשון בסדרה, המנה, מספר האיברים בסדרה אשר הופיעו ברשימה המקורית. דוגמא: הרשימה הבאה: list->3-> 6-> 12-> 24-> -4-> 12-> -36-> 4-> 8-> 16-> 32-> 64-> 128-> 2-> -10-> 50-> -250->. תהפוך לאחר הקריאה לפונקציה לרשימה זו: list-> 3-> 2-> 4-> -4-> -3-> 3-> 4-> 2-> 6-> 2-> -5-> 4->. הערה: ניתן להניח כי אין חפיפה בין הסדרות, כלומר, לא יהיה מקרה בו האיבר האחרון בסדרה מסוימת שייך גם לסדרה העוקבת. יש לשחרר כל זיכרון שאין בו צורך יותר. ניתן להגדיר פונקציות עזר כרצונכם. דגש: - 6 -
שאלה (20 6 נקודות) אגודת הסטודנטים של האוניברסיטה בשיתוף עם אגודת הסטודנטים של המכללה האקדמית מציעה שירותי טרמפים לסטודנטים דרך אתר אינטרנט. שתי האגודות מרכזות בקשות יומיות לטרמפים בשני קבצים (אחד לכל מוסד) שבהם כל שורה מתארת בקשה ומכילה את הפרטים הבאים: 20 תווים שם הסטודנט 15 תווים אזור יציאה 15 תווים אזור יעד 2 ספרות שעת יציאה קוד אזור יציאה 3 ספרות 3 ספרות קוד אזור יעד הקבצים ממוינים לפי שעת יציאה בסדר עולה ומיון משנה לפי קוד אזור יציאה ומיון שלישי לפי קוד יעד גם בסדר עולה. בנוסף האגודות מרכזות הצעות יומיות לטרמפים בשני קבצים (אחד לכל מוסד) שבהם כל שורה מתארת הצעה ומכילה את הפרטים הבאים: 20 תווים שם הסטודנט 15 תווים אזור יציאה 15 תווים אזור יעד 2 ספרות שעת יציאה 3 ספרות קוד אזור יציאה 3 ספרות קוד אזור יעד ספרה אחת ישיבה מספר מקומות הקבצים ממוינים לפי שעת יציאה בסדר עולה ומיון משנה לפי קוד אזור יציאה ומיון שלישי לפי קוד יעד גם בסדר עולה. האגודות מעוניינות להפיק דוח יומי של כל הסטודנטים יחד (ולא משנה מאיזה מוסד) שלא ניתן יהיה לספק את בקשתם. כל שורה בקובץ מכילה את הנתונים הבאים: 15 תווים אזור יציאה 15 תווים אזור יעד 2 ספרות שעת יציאה 3 ספרות קוד אזור יציאה 3 ספרות קוד אזור יעד 2 ספרות ) מספר סטודנטים שלא ניתן לספק בקשתם) מספר מקומות חסרים מקומות שלא חסרים לא מופיעים בקובץ. הקובץ יהיה ממוין לפי שעת יציאה בסדר עולה ומיון משנה לפי קוד אזור יציאה ומיון שלישי לפי קוד יעד גם בסדר עולה. כתבו פונקציה filename) int tremp(file* request[2], FILE* offer[2], char* שמקבלת כפרמטרים request מערך של שני מצביעים של קבצי הבקשות של שתי האגודות, offer מערך של שני מצביעים של קבצי ההצעות של שתי האגודות, ומחרוזת filename שמכילה את השם של הקובץ החדש של המקומות החסרים שהפונקציה יוצרת. במקרה וארעה שגיאה בפתיחה או סגירה של אחד הקבצים הפונקציה תחזיר 0, אחרת 1. שימו לב! חלק מהכרזות הפונקציה כתוב בדף התשובות בכל הקבצים אין תווי הפרדה בין השדות אין לעבור על קובץ יותר מפעם אחת. אין להעתיק קובץ למבנה נתונים אחר (מערך, רשימה משורשרת, עץ,קובץ אחר...) - 7 -
רשימת פונקציות קלט/פלט: INPUT/OUTPUT FUNCTIONS PROTOTYPES Open/Close a file FILE *fopen( char *filename, char *mode ); int fclose(file *stream); Repositions the file pointer to the beginning of a file void rewind( FILE *stream ); Get/put a character int fgetc( FILE *stream ); int fputc( int c, FILE *stream ); Get/put a string char *fgets( char *string, int n, FILE *stream ); int fputs( const char *string, FILE *stream ); Formatted Input/Output int fscanf( FILE *stream, const char *format [, argument ]... ); int sscanf( const char *string, const char *format [, argument ]... ); int fprintf( FILE *stream, const char *format [, argument ]...); int sprintf( char *string, const char *format [, argument ]...); Remove a file int remove(const char* filename); Rename a file int rename(const char* oldname, const char*newname); ב ה צ ל ח ה! - 8 -