םדקתמ תונכת c תפשב - האקדמיתhbinsky/c content/exercises ver 2.pdf- 5 - . 8x^4 +...

36
- 1 - תכנות מתקדם בשפתC חוברת תרגילים

Upload: others

Post on 24-Feb-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 1 -

תכנות מתקדם

Cבשפת

חוברת תרגילים

Page 2: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 2 -

קלט פלט

1שאלה

10 כתבו תוכנית המדפיסה לוח כפל בגודל .א 10× .

MaxMult, ומדפיסה לוח כפל בגודל MaxMultכתבו תוכנית המקבלת מספר, .ב MaxMult×.

יודפס: MaxMult=4לדוגמא עבור:

1 2 3 4

2 4 6 8

3 6 9 12

4 8 12 16

הנחיות לשני הסעיפים

ההדפסות צריכות להיות בצורת טבלה ועל כל שדה בטבלה להיות מיושר לימין (כך שבכל טור ספרת האחדות תהיינה אחת מעל השנייה, ספרת העשרות תהיינה אחת מעל השנייה, וכך הלאה עבור כל

הספרות) רווח אחד הקפידו לא להכניס רווחים מיותרים (לפני המספר שבפינה הימנית תחתונה צריך להופיע

בדיוק).

2שאלה כתבו את הפונקציה:

void printFormattedIntegers(char* format, char* numbers)

, המכילה פורמט להדפסה של מספרים וכן מחרוזת, formatהפונקציה מקבלת כקלט מחרוזת,

numbersם. , המכילה מספרים שלמים בבסיס דצימלי מופרדים במספר כלשהו של רווחים לבני

. כך format-, בהתאם לתווי ההסבה שבnumbersעל הפונקציה להדפיס את המספרים מהמחרוזת

, תו ההסבה השני numbers-יקבע כיצד ייוצג המספר הראשון ב format-שתו ההסבה הראשון ב ).printf-יקבע כיצד ייוצג המספר השני וכך הלאה (בדומה ל

): printf -בה הבאים (כמו במחרוזת הפורמט יכולה להכיל את תווי ההס

%d – ממירint של המספר עשרונילטקסט המכיל ייצוג %x – ממירint של המספר16(בסיס הקסהדצימלילטקסט המכיל ייצוג ( %o – ממירint של המספר8(בסיס אוקטלילטקסט המכיל ייצוג (

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

%b – ממירint של המספר2(בסיס בינארילטקסט המכיל ייצוג ( %r – ממירint של המספר רומילטקסט המכיל ייצוג

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

Page 3: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 3 -

: דוגמאות הקריאה:

printFormattedIntegers("Dec: %d Hex: %x Roman: %r"," 123 10

9")

תגרום להדפסת הפלט:Dec: 123 Hex: A Roman: IX

הקריאה:

printFormattedIntegers("%b in Binary is %o in Octal" ,"18 18")

תגרום להדפסת הפלט:10010 in Binary is 22 in Octal

:הנחיות היעזרו בוויקיפדיה כדי למצוא את התיאור המלא של שיטת הספירה הרומית: .1

http://he.wikipedia.org/wiki "חפשו את הערך:"ספרות רומיות אכן מכילה מספרים numbersהניחו כי הקלט לפונקציה תקין, כלומר הניחו כי המחרוזת .2

כיל מחרוזת פורמט חוקית וכן מ formatומופרדים ברווח לבן וכי 10שלמים מיוצגים בבסיס שמספר תווי ההסבה במחרוזת הפורמט מתאים למספר המספרים שהתקבלו במחרוזת

numbers. printf ,scanf ,sscanf ,sprintfהשתמשו ככל הניתן בפונקציות הקלט/פלט שנלמדו בשיעור .3

וכו'.בהחלט ניתן (חפשו תיעוד המסביר כיצד להשתמש בה) אך strtokניתן להיעזר בפונקציה .4

להסתדר גם בלעדיה. הגדירו פונקציות עזר וחלקו את הבעיה לתת בעיות. .5

Page 4: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 4 -

מצביעים והקצאות דינאמיות

1שאלה כתבו את הפונקציה: א.

int** pointerSort(int* arr, unsigned int size, char ascend_flag);

ודגל, size, את גודלו, arrהפונקציה מקבלת כקלט מערך של מספרים שלמים,

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

arrמצביעים, כך שהמצביעים במערך יצביעו על איברי מערך של החזיר על הפונקציה ל

.ascend_flagפי -עלבצורה ממוינת

של המערך המוחזר מצביע לאיבר 0-המצביע בתא ה ascend_flag=1אם כלומר, המינימלי.

.merge-sortממשו את המיון בשיטת :הערה

= arr הוא arr: אם המערך לדוגמא

:המערך המוחזר יהיה אז

כתבו גרסא נוספת לפונקציה. הפעם כותרת הפונקציה תהיה: ב.void pointerSort(int* arr, unsigned int size,

char ascend_flag, int*** pointers);

ascend_flagודגל, sizeגודלו, , arrהפונקציה מקבלת מערך של מספרים שלמים, הפעם על הפונקציה להחזיר אשר אם ערכו שונה מאפס המיון הוא עולה, אחרת המיון יהיה יורד.

מצביעים. המערך את כפרמטר פלט

2שאלה מהצורה:עם מקדמים שלמים בהינתן פולינום

נגדיר רשומה לייצוג מונום כנ"ל באופן הבא: כל איבר בפולינום נקרא מונום.typedef struct monom{

int coefficient; //המקדם

int power; // החזקה

}Monom;

:, המקייםMonomמטיפוס של רשומות מערך: מיםמבנה הנתונים לייצוג פולינו

.0מונום שמקדמו יכיללא מערךה •

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

כתבו תוכנית הקולטת מהמשתמש שני פולינומים, ומדפיסה את פולינום הסכום שלהם ואת פולינום

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

של זוגות (מקדם וחזקה). באורך לא ידועכל פולינום בקלט יהיה שורה .1 למשל השורה: כך

2 4 -5 1 0 6 6 4 -8 0 7 3

4מייצגת את הפולינום: 38 7 5 8x x x+ − −. .0הדפסת פולינום צריכה להיות בסדר חזקות יורד, ללא מקדמים שהם .2

1 1

1 1 0...n n

n nC X C X C X C

−+ + + +

Page 5: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 5 -

4למשל את הפולינום: 38 7 5 8x x x+ − .8x^4 + 7x^3 - 5x - 8יש להדפיס: −

3אלה ש כתוב תוכנית הקולטת שורות טקסט מהמשתמש ואוגרת אותן במערך של מחרוזות.

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

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

משחזרת את השורה האחרונה שהוכנסה למאגר. !!

!n שורה מספר את משחזרתn שגיאהתודפס הודעת -. במידה ואין כזו . ) ן רציף מתחילת התוכנית ועד סיומהפמספרי השורות ניתנים באו(

!L השורה האחרונה. מספראת משחזרת

!~str לא הופיעה בה המחרוזת משחזרת מהמאגר את השורה האחרונה שstr . מידה ואין כזו, תודפס הודעת שגיאה.ב

!str שהתחילה במחרוזת משחזרת מהמאגר את השורה האחרונהstr .מידה ב הודעת שגיאה.ואין כזו, תודפס

!print .מדפיסה את תוכן המאגר. כל שורה תופיע אחרי מספר השורה )רציף מתחילת התוכנית ועד סיומהמספרי השורות ניתנים באופן (

!quit .יציאה

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

דוגמת הרצה

)רגילוהפלט שהתוכנית מדפיסה מופיע בפונט מודגש ונטוי(הקלט מהמשתמש מופיע בפונט Please enter the history storage size

> 5 The storage size was set to 5

> some text

> some more text

> and more text

> !2 some more text

> hello world

> !! hello world

> !! hello world

> !2 Could not restore line number 2, currently lines 3-7 are

in the storage

> !print 3. and more text

4. some more text

5. hello world

6. hello world

7. hello world

> !~hello some more text

> !some some more text

>!L Number of last line is 9

Page 6: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 6 -

> !quit Thanks for using the history application, bye bye

הערות לא ניתן להניח אורך שורה מקסימאלי .1 ניתן להניח כי כל שורה שאינה פקודת שחזור תתחיל באות אנגלית .2 O(1)פתרון יעיל הוא פתרון אשר פעולת הכנסה למאגר תתבצע בזמן .3

4שאלה

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

.שלאחר ההכפלהירה מחרוזת חדשה המכילה את הרצף הפונקציה מחז

לדוגמא:

strrep ("hello world", “l”) שנה את המחרוזת הראשונה לת “hellllo worlld"

), יש לבצע את NULLאם הפונקציה הופעלה בשנית, עם פרמטר ראשון שהוא המחרוזת הריקה ("" או על תוצאת ההפעלה הקודמת של הפונקציה. ההכפלה

לדוגמא:

strrep (NULL, "or") שנה את המחרוזת הראשונה לת “helllloo woorrlld"

Page 7: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 7 -

רשימות מקושרות

1שאלה הבאים לייצוג רשימה מקושרת של תווים:נתונים המבנים

typedef struct list_node

{

char* dataPtr;

struct list_node* next;

}ListNode;

typedef struct list

{

ListNode* head;

ListNode* tail;

}List;

המקושרתהרשימה שנתוניה הם ספרות, ואותיות אנגליות קטנות בלבד. רשימה מקושרת נתונה

במקורה הכילה את המידע הבא על תלמיד: שמו הפרטי של התלמיד (המופיע באותיות קטנות) אות אחר אות ברשימה, ואחריו מופיע ציונו הממוצע (הניתן בספרות המייצגות מספר חיובי שלם) סיפרה אחר

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

היה uהיה הנתון בצומת הראשון, mכאשר muℓℓy94דוגמה: רשימה שבמקור הכילה את התווים

), שונתה וכעת היא מכילה את 94, וציונו muℓℓyהנתון בצומת השני, וכ"ו (כלומר שמו הפרטי הוא שני, וכ"ו).הוא הנתון בצומת ה 9הוא הנתון בצומת הראשון, m(כאשר m9uℓ4ℓyהתווים:

יבוא אחרי m ,ℓיבוא אחרי uשימו לב כי סדר התווים והספרות המקורי נשמר בתוך הערבול. (לדוגמא,

u.('וכו , מעורבלת ומחזירה מבנה לייצוג תלמיד (שיוגדר להלן) המכיל את שמו רשימה כתבו פונקציה המקבלת

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

של הפונקציה הוא: prototype –ה Student unScramble (List lst);

כאשר מבנה של תלמיד מוגדר להלן:

typedef struct student

{

List first;

int grade;

} Student;

הוא רשימה המייצגת את שמו הפרטי של הסטודנט אות אחר אות. firstהשדה •

הוא מספר המייצג את ממוצע ציוניו של הסטודנט. gradeוהשדה •

הערות:

אין להשתמש בהקצאה דינאמית, אלא לשנות מצביעים ברשימת הקלט. •

Page 8: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 8 -

2שאלה נתונה ההגדרה הבאה לייצוג רשימה מקושרת של מספרים שלמים:

typedef struct listNode{

int* dataPtr;

struct listNode* next;

}ListNode;

typedef struct list

{

ListNode* head;

ListNode* tail;

}List;

כתבו את הפונקציה הבאה, בארבע גרסאות:List merge(List lst1, List lst2);

של ערכים יורדבסדר ממוינות, שתי רשימות מקושרות lst2-ו lst1הפונקציה מקבלת כקלט

. dataPtrעליהם מצביעים השדות הפונקציה למזג את שתי הרשימות לרשימה ממוינת אחת המכילה את כל האיברים של רשימות הקלט. על

על הפונקציה להחזיר את הרשימה הממוזגת.

. רשימה חדשהועליה ליצור איננה רקורסיביתבגרסא זו, הפונקציה א.

רשימות (בסוף ריצת הפונקציה שתי ה lst2 -ו lst1הפונקציה לא תשנה הצבעות ברשימות נותרות ללא שינוי).

ועליה למזג את שתי הרשימות לרשימה אחת ממוינת ע"י איננה רקורסיביתבגרסא זו, הפונקציה ב.

בלבד (ללא שימוש בהקצאות חדשות). שינוי מצביעים . רשימה חדשהועליה ליצור רקורסיביתבגרסא זו, הפונקציה ג.

.שינוי מצביעיםה למזג את שתי הרשימות ע"י ועלי רקורסיבית בגרסא זו, הפונקציה ד.

ד' הפונקציה אינה חייבת להיות רקורסיבית בעצמה, היא יכולה להיות פונקציה -בסעיפים ג' ו : הערה העוטפת פונקציה רקורסיבית (פונקציה אשר מפעילה לפונקציה רקורסיבית).

Page 9: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 9 -

3שאלה מספרים שלמים:נתונה ההגדרה הבאה לייצוג רשימה מקושרת של

typedef struct listNode{

int* dataPtr;

struct listNode* next;

struct listNode* prev;

} ListNode;

typedef struct list

{

char sgn;

ListNode* head;

ListNode* tail;

} List;

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

נייצג ברשימה: 197למשל את המספר

;void printNumber(List num) כתבו את הפונקציה: א.מספר המיוצג ברשימה כפי שתואר, ומדפיסה אותו. (הפונקציה יכולה להיות רקורסיבית או שמקבלת

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

ב. כתבו את הפונקציה:

void subtractNumbers(List n1, List n2, List* result);

להצביע resultייצגות שני מספרים ומצביע לרשימה שלישית ומעדכנת את רשימות שמ 2שמקבלת .n1 - n2הפרש המספרים על רשימה השלישית המייצגת את

;void modNumbers(List n1, List n2 , List* mod) כתבו את הפונקציה: ג.

להצביע על modרשימות שמייצגות שני מספרים ומצביע לרשימה שלישית, ומעדכנת את 2שמקבלת .שארית החלוקה בין שני המספריםרשימה השלישית המייצגת את

להשתמש באלגוריתם הממיר את המספרים המיוצגים ברשימות למשתנים איןג' - : בסעיפים ב' והערה

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

7 9 1

Page 10: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 10 -

4שאלה

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

המבנה לעיל שומר את הנקודות:(5,3), (5,8), (7,4), (9,-4), (9,9), (9,9)

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

. שימו לב כי המבנה הנ"ל עושה שימוש בשני Yזהה ואשר נבדלות רק בערכי הקורדינטה Xקורדינטה ת אשר כל אחת מהן ממויינת.נים של רשימוסוגים שו

typedef struct XlistNode{

} XListNode;

typedef struct YlistNode{

} YListNode;

typedef struct Ylist

{

} YList;

typedef struct list

{

} List;

כתבו את הפונקציה .א

unsigned int getPairOccurrences(List coord_list,

int x, int y);

coord_list.-ב (x,y) הנקודהאשר סופרת ומחזירה כמה פעמים מופיעה כתבו את הפונקציה .ב

unsigned int getYOccurrences(List coord_list, int y);

אשר שיעור כאלו כלומר coord_list.-נמצאות ב (y,*)נקודות אשר סופרת ומחזירה כמה .yשווה לפרמטר שלהן Yהקורדינטה

Page 11: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 11 -

כתבו את הפונקציה .ג

unsigned int getXOccurrences(List coord_list, int x);

שיעור כלומר כאלו אשר coord_list.-נמצאות ב (*,x)אשר סופרת ומחזירה כמה קורדינטות .xשווה לפרמטר שלהן Xהקורדינטה

כתבו את הפונקציה .ד

int insertCoordinate(List *coord_list, int x, int y);

, 1חזיר הפונקציה ת. אם הנקודה נמצאת כבר, (x,y) הנקודהאת coord_list -אשר מוסיפה ל נקודה.בכל מקרה, הפונקציה תוסיף את ה .0 תחזיראחרת הפונקציה

כתבו את הפונקציה .ה

int removeCoordinate(List *coord_list, int x, int y);

-במופיעה יותר מפעם אחת . אם הנקודה (x,y) הנקודהאת coord_list -אשר מוחקת מ

coord_list .במקרה וזו הנקודה היחידה עם שיעור ה, יש למחוק רק את אחד המופעים-X ,שצויין .X-יש למחוק גם את התא המתאים ברשימת שיעורי קורדינטות ה

לדוגמא, לאחר הפעלת

removeCoordinate( &coord_list, 7, 4); ה שבעמוד הקודם, יתקבל המבנהעל המבנ

:להחזיר את אחד מהערכים הבאים removeCoordinateעל הפונקציה , 1 תחזירהפונקציה לא נמצאה,אם הנקודה

,2תחזיר הפונקציה אם יש מופע נוסף לנקודה, ,3שצויין, הפונקציה תחזיר Xאם זו הייתה הקורדינטה היחידה עם השיעור

.0הפונקציה תחזיר בכל מקרה אחר,

Page 12: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 12 -

עצים בינאריים

1שאלה

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

typedef struct treeNode

{

int data;

struct treeNode *left;

struct treeNode *right;

TreeNode;}

typedef struct tree

{

TreeNode *root;

}Tree;

הפונקציה :כתבו את

int HowMany (Tree tr)

מתקיים התנאי הבא: מספר עבורםתתי העצים , ומחזירה את מספר trהפונקציה מקבלת כפרמטר עץ,

עץ.תת ההאיברים בכל לפחות מחצית מ תת העץ (כולל השורש) מהווההאברים החיוביים ב

(הערה: עלה שהנתון בו הינו חיובי נכלל בספירה).

תתי עץ. 6, כלומר צמתים 6לדוגמא, בעץ שלהלן ישנם

) מקיימים את התכונה, והפונקציה שתקבל את העץ 5ואת 3, את 12מתוכם (האיברים שמכילים את 3

.3הזה כפרמטר תחזיר

12

3

3-

5 4-

1-

Page 13: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 13 -

2שאלה

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

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

חיבור, חיסור, כפל, חילוק ומודולו. –(בינריות) בסיסיות (אופרטורים)

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

( 4 + 5 ) ( (3 + 7) * 9) ( (2 + 5) * (8 / 2))

נגדיר עץ ביטוי באופן הבא: .עץ יכול להכיל אופרטור או אופרנדצומת ב

צומת עם בנים יכיל אופרטור אותו יש להפעיל על הביטויים המיוצגים ע"י תת העץ השמאלי ותת העץ הימני.

עלים יכילו אופרנדים.

דוגמאות:

(4+5)

((3 + 7) * 9)

Page 14: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 14 -

( (2 + 5 ) * (8 / 2) )

תבו תכנית הקולטת מהמשתמש מחרוזת המכילה ביטוי לפי ההגדרות בשאלה, בונה עץ ביטוי ומחשבת כ אינה ביטוי תקין. על התכנית להציג הודעת שגיאה אם המחרוזתאת ערך הביטוי תוך שימוש בעץ.

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

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

Page 15: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 15 -

3שאלה נתונים המבנים הבאים עבור עץ בינארי ועבור רשימה מקושרת:

typedef struct listNode {

int data;

struct listNode* next;

} ListNode;

typedef struct list {

ListNode* head;

ListNode* tail;

} List;

typedef struct treeNode {

int data;

struct treeNode* parent;

struct treeNode* left;

struct treeNode* right;

} TreeNode;

typedef struct tree{

TreeNode* root;

List leafList; /* שימה מקושרת של כל העלים בעץר */

} Tree;

כתבו את הפונקציה הבאה:

#define LEFT 0

#define RIGHT 1

Tree AddNode (Tree *tr, TreeNode *p,

int branchSelect , int data);

. pאותו יש להכניס לעץ מתחת ל dataנתון חדש , p , צומת בעץ הבינריtr הפונקציה מקבלת עץ בינרי

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

מופיעה גם רשימה מקושרת של עלים. הרשימה צריכה להיות מעודכנת ונכונה שימו לב שבמבנה העץ

לאחר כל הוספה של איבר לעץ.

Page 16: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 16 -

דוגמא לעץ כזה:

27בצד שמאל של העלה המכיל את הערך 16לשם ההבהרה, אם נקבל בקשה להכניס את המספר בקריאה:

AddNode (tr, 27מכיל את הערך הכתובת של העלה , LEFT , 16);

נקבל את מבנה הנתונים הבא:

1

8

43

27

23

52

2 5 8 16

tr

16

:נוספותהבהרות

, שורש זהבמקרה להכניס את האיבר במקום שורש העץ. כוונה היא ה NULLהוא pערכו של ם א •

.branchSelect -בהתאם לכתוב ב איבר החדשיהפוך להיות הילד של ה העץ

• p ולא רק על עלים )איברים פנימיים בעץ(ילדים כבריכול להצביע גם על איברים בעץ שיש להם .יהפוך של ילד שקיים כבר, הילד הנוכחי במקומוובמידה והאיבר החדש אמור להיכנס , זהכבמקרה

, הוא pאם הוא היה הילד השמאלי של כלומר,המקורי. מיקומובהתאם ל איבר החדשיות הילד של הלה יהפוך להיות הילד השמאלי של האיבר החדש.

העלים תמיד מכילה את כל העלים מסודרים לפי סדר הופעתם בעץ, משמאל לימין.רשימת •

נתון לא מופיע פעמיים בעץ.ניח שלהפשטות, ניתן לשם •

Page 17: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 17 -

4שאלה עץ בינארי מוגדר כך:

typedef struct treeNode{

int data;

struct treeNode* left;

struct treeNode* right;

} TreeNode;

typedef struct tree{

TreeNode* root;

} Tree;

כתבו את פונקציה:

void printByLevels(Tree tr);

, אחריהם 1, אחריו את נתונים ברמה 0לפי רמות (קודם את הנתון ברמה trהמדפיסה את הנתונים בעץ . , וכך הלאה), כל רמה תודפס משמאל לימין2את הנתונים ברמה

)על הפונקציה לרוץ ביעילות )nΘ כאשר ,n .הוא מספר הצמתים הכולל בעץ

למשל עבור העץ:

1 9 7 4 5 2 3יודפס:

: ותהער . בכדי לעמוד בדרישות היעילות ייתכן ותרצו להשתמש במבנה נתונים נוסף.1 אין להשתמש במשתנים סטאטיים.. 2

5

9 4 7

2

3

1

Page 18: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 18 -

קבצים

:1שאלה .xפרמטרים. הפרמטר הראשון יהיה שם של קובץ בינארי והשני מספר שלם, 2כתבו תכנית המקבלת

נתון שהקובץ בנוי בפורמט הבא:

רצף המציין את גודלה, ולאחר מכן intמטיפוס מחרוזות, כאשר לפני כל מחרוזת יש מספר xבקובץ ישנן . כל מחרוזת מורכבת מאותיות )' בסופה\0ללא '(המחרוזת עצמה באורך זה של תווים המייצגים את

קטנות וגדולות בלבד.

:הקובץ מבחינה לוגית יכול להיראות 3הוא xלמשל, אם 5aBCde6aaBTRy4BBbb

אותיות 6השניה באורך ,"aBCdeאותיות והיא " 5מחרוזות, הראשונה באורך 3כלומר בקובץ ישנן ."BBbb"אותיות והיא 4אורך והשלישית ב "aaBTRy"והיא

על התכנית לבצע את המשימות הבאות:

וכל מחרוזת בו היא האותיות הקטנות בלבד הלקוחות xלייצר מערך של מחרוזות, שגודלו • 3בהתאמה מכל מחרוזת שבקובץ. למשל, עבור הדוגמא הקודמת, התכנית תייצר מערך של

מחרוזות ואלו הן: ."bb"והשלישית "aay"השניה "ade"הראשונה היא

(מבחינה לקסיקוגרפית). למשל, לייצר קובץ טקסט אליו יודפסו המחרוזות בצורה ממויינת • קובץ הטקסט שיווצר יראה:בדוגמא שלנו

בסוף. "txt."שמו של הקובץ המיוצר הוא כשמו של קובץ הקלט, בתוספת . "file.bin.txt" יווצר יהיהישם הקובץ ש "file.bin" שם קובץ הקלט הוא: נניח שלמשל

aay ade bb

Page 19: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 19 -

2שאלה

נתונה ההגדרה הבאה לרשומה:

typedef struct employee { int name_length; char * name; float salary; } Employee;

.file2 - ו file1קבצים בינאריים, להלן 2פרמטרים. הפרמטרים הינם שמות של 2כתבו תכנית המקבלת כלומר בנוי בפורמט הבא: Employeeהינו קובץ שמאחסן אברים מסוג file1נתון שהקובץ המציין את intמתחיל במספר מטיפוס Employeeאינו ידוע), כאשר כל xאיברים ( xבקובץ ישנם

ולאחר מכן )בסופה' \0ללא '(אורך השם, לאחר מכן רצף באורך זה של תווים המייצגים את השם עצמו המהווה את המשכורת. floatמספר בייצוג

:גית יכול להיראותומבחינה לקובץ ה 2הוא xלמשל, אם 5danny7500.50 4ruti12350.75

7500.50" ומשכורתו dannyאותיות והוא " 5עובדים, הראשון שמו מכיל 2כלומר בקובץ ישנם .12350.75שכורתה ומ "ruti"אותיות והוא 4והשניה שמה מכיל

. כמו כן המספרים (בקובץ הבינארי כמובן אין רווחים ובדוגמא יש רווח בין העובדים להמחשה בלבד ).צגו בקובץ באופן בינאריויי

המהווים תוספת, בהתאמה, למשכורותיהם של העובדים floatמספרים מסוג xהקובץ השני מכיל .file1הרשומים בקובץ

.300 - ו 100הקודמת, הקובץ יכול להכיל את המספרים למשל, בהמשך לדוגמא

₪. 300 - ומשכורתה של רותי ב₪ 100 -אמורה לעלות ב dannyמשמעות הדבר שמשכורתו של

.file1א כמספר העובדים בקובץ וה file2בקובץ תוספות השכר ניתן להניח שמספר

כך שיכיל את העובדים ומשכורותיהם המעודכנות (בהתאם לתוספות file1עדכן את הקובץ לעל התכנית מערך של תוך שימוש ב ) בסדר יורד מהעובד בעל השכר הגבוה ביותר לנמוך ביותרfile2 -ב ותהרשומ

.file1 גודלו של המערך יהיה כמספר העובדים בקובץכאשר Employee -ל מצביעים

Page 20: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 20 -

3שאלה

המורכבת מתווים.בשאלה זו נעסוק בייצוג של תמונה

נתונה ההגדרה הבאה לייצוג תמונה טקסטואלית:

typedef struct textPicture{

int numRows;

int numCols;

PicList pic;

}TextPicture;

מחזיקים את ממדי התמונה (מספר השורות ומספר העמודות בתמונה numCols - ו numRowsכאשר

ם מהם מורכבת התמונה ברשימה מקושרת.שומרים את התווי pic -בהתאמה), וב

(ממנו תוגדר הרשימה של התווים בתמונה) מוגדר באופן הבא: PicListהטיפוס

typedef struct picListNode{

PicChar data; //תו בתמונה

struct picListNode* next;

}PicListNode;

typedef struct picList{

PicListNode* head;

PicListNode* tail

}PicList;

. והוא מוגדר באופן הבא:PicCharכל תו בתמונה (איבר ברשימה) הוא מטיפוס

typedef struct picChar{

Point position; //מיקום התו

char ch; //התו

}PicChar;

typedef struct point{

int x;

int y;

}Point;

Page 21: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 21 -

היות שצפויים להיות הרבה תווי רווח בתמונה, לצורך צמצום גודל הייצוג של התמונה, יישמרו .א

) רק תווים השונים מהתו רווח.TextPictureשל picברשימה המקושרת (שדה למשל כדי לייצג את התמונה הבאה:

- יהיו מאותחלים ב numCols -ו numRows, אשר השדות TextPictureנגדיר משתנה מטיפוס

יכול להיות הרשימה הבאה: picבהתאמה, והשדה 8 - וב 5

כתבו את הפונקציה הבאה:

void paintTextPicture(TextPicture textPic, char* filename);

בייצוג שתואר לעיל ו"מציירת" את התמונה הנ"ל באופן מפורש textPicהפונקציה מקבלת תמונה

.filenameלקובץ (טקסט) ששמו

ייווצר הקובץ הבא:למשל עבור התמונה לעיל

: ותהער

וביחס לנקודה זו נקבעים המיקומים של שאר (0 ,0). התו השמאלי עליון של התמונה ממוקם ב: 1

התווים.

. התווים ברשימה לא מופיעים בסדר ממוין כלשהו.2

(4,2,'$') (3,1,'#') (2,2,'$') (3,2,'#') NULL

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n'

' ' ' ' ' ' '#' ' ' ' ' ' ' ' ' '\n'

' ' ' ' '$' '#' '$' ' ' ' ' ' ' '\n'

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n'

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n'

#

$ # $ שורות 5

עמודות 8

Page 22: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 22 -

הבאה:כתבו את הפונקציה .בTextPicture * openTextPicture(char* filename);

שם של קובץ טקסט, המכיל תמונה טקסטואלית. ,filenameהפונקציה מקבלת כקלט את

אשר מהווה ייצוג בזיכרון לתמונה ,TextPictureלנתון מטיפוס מצביעהפונקציה מייצרת ומחזירה

) TextPictureשל picווים (שדה . הרשימה שמכילה את התfilenameהנמצאת בקובץ , בכל עמודה סדר התווים יהיה מלמעלה למטה. עמודותמסודרים לפי שאינם רווחתורכב רק מהתווים

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

למשל עבור התמונה הבאה:

5יהיו numCols -ו numRows, אשר השדות TextPictureהפונקציה תחזיר מצביע על נתון

יהיה הרשימה הבאה: picבהתאמה, והשדה 8 -ו

: ותהער

וביחס לנקודה זו נקבעים המיקומים של שאר (0 ,0). התו השמאלי עליון של התמונה ממוקם ב: 1

התווים.

. ניתן להניח כי התמונה מכילה תווים השונים מרווח.2

.'n\'. בסוף כל שורה בתמונה מופיע התו 3

(2,2,'$') (3,1,'#') (3,2,'#') (4,2,'$') NULL

#

$ # שורות $5

עמודות 8

Page 23: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 23 -

כתבו את הפונקציה הבאה: .גvoid replicatePicture(TextPicture srcPic, int m, int n,

char* repPicFileName);

, המכיל תמונה TextPictureמשתנה מטיפוס ,srcPicהפונקציה מקבלת כקלט את טקסטואלית.

, שיכיל תמונה טקסטואלית שהיא ריצוף repPicFileNameקובץ טקסט בשם הפונקציה מייצרת

.srcPicעותקים של התמונה המקורית של m-by-n בגודל של

הבאה: התמונשמכיל את ה srcPicועבור n=2 -ו m=3 עבור למשל

קובץ הטקסט אשר יכיל את התמונה הבאה:ייצר את הפונקציה ת

: ותהער

מכילה תווים השונים מרווח.המקורית . ניתן להניח כי התמונה 1

.'n\'. בסוף כל שורה בתמונה מופיע התו 2

#

$ # שורות $5

עמודות 8

# #

$ # $ $ # $

# #

$ # $ $ # $

# #

$ # $ $ # $

שורות 15

עמודות 16

Page 24: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 24 -

כתבו את הפונקציה הבאה: .דvoid mergePictures(TextPicture* bigPic,

char* smallPic);

, המכיל תמונה TextPictureמשתנה מטיפוס ,bigPicהפונקציה מקבלת כקלט את

., שם של קובץ טקסט, המכיל תמונה טקסטואליתsmallPicטקסטואלית ואת

בכל אחד מהמימדים (גם השורות וגם bigPic -מ הקטנה ממשהיא תמונה smallPicכי נתון העמודות).

smallPic -לתמונה שהיא איחוד של שתי התמונות כך ש bigPicת א עדכןעל הפונקציה ל

.bigPicאת הפינה הימנית התחתונה של מחליפה

הבאה:המכיל את התמונה bigPicלמשל עבור

הבאה: smallPicועבור

כיל את התמונה הבאה:לה bigPicאת עדכןהפונקציה ת

: ותהער

.'n\'בסוף כל שורה בתמונה מופיע התו

# # #

# # $ $

# # $ $

# $ $

$ $ $ $

שורות 5

עמודות 8

שורות 5

עמודות 8

# #

# #

# # #

שורות 3

עמודות 3

# # #

# # $ $

# # # #

# # #

$ # # #

Page 25: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 25 -

4שאלה נתונה ההגדרה הבאה של רשומה שמירת נתונים על תלמיד:

typedef struct student{

char* name;

int average;

}STUDENT;

בקובץ בינארי לפי הפורמט הבא:מאגר של תלמידים נשמר

.n - , נסמנו בבקובץ התלמידים הנמצאותרשומות את מספרהמציין short intמטיפוס מספר •

רשומות, כאשר כל רשומה בנויה באופן הבא: nרצף של •

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

.len -ב

בסוף רצף התווים '0\'המייצגים את שמו של התלמיד הנוכחי (אין תווים, lenרצף של • הנ"ל).

המייצג את ממוצע ציוניו של התלמיד הנוכחי. intמטיפוס רמספ •

הפורמט לעיל. התוכנית המכיל נתוני תלמידים עפ"יתוכנית המקבלת כפרמטר שם של קובץ וכתבא. המכיל נתונים של היסט יחסית לתחילת קובץ ים (קובץאינדקס קובץ קובץ התלמידים ר עבורויצת

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

."ind." הסיומת בתוספתהשם של הקובץ המקורי להיות יםהאינדקס ץבוק של שמועל

ככל האפשר.: את המיון יש לבצע ע"י אלגוריתם יעיל הערה

ב. כתבו את הפונקציה הבאה:

char ** findAverageGrade(char* database, int avgGrade,

int * resSize);

, המייצגת שם של קובץ המכיל נתוני תלמידים (לפי databaseהפונקציה מקבלת כקלט מחרוזת

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

avgGrade אוNULL תלמיד כזה באף אם אין- database. במשתנהresSize יוחזר מספר התלמידים הנ"ל.

: ותהער

הניחו שהפונקציה הנ"ל נקראת רק אחרי שכבר נוצר קובץ אינדקסים, כפי שהוגדר בסעיף א', עבור .1

.databaseהקובץ שימו לב ליעילות זמן הריצה של הפונקציה אותה אתם כותבים. .2

Page 26: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 26 -

ביטים

1שאלה

חיפוש בספר טלפונים. מחרוזות: 2נניח כי לכל לקוח בספר טלפונים יש

typedef struct _client

{

char id[9]; // “12345678”

char phone[12]; // “054-1234567”

} Client;

’.0\‘ספרות (ללא ספרת ביקורת) ובסוף 8בשדה ת.ז. ישנן ’ 0\‘ –ו ספרות המספר עצמו 7אח"כ (מקף) ו’ -‘ספרות קידומת, סימן הפרדה שלושטלפון יש הבשד

בסוף. בתים ללקוח. 21בסה"כ נשמרים

נרצה להקטין את כמות הבתים הנשמרת ללקוח, מבלי לאבד אינפורמציה.

נשתמש במבנה הבא: typedef struct _short_client

{

unsigned char short_id[4];

unsigned char short_phone[5];

} Short_client;

.asciiלקוח הינם עוקבים בטבלת לעים המשתתפים במידע שנשמר וכל התושימו לב כי כי הוא קבוע ומיקומו ידוע. כאשר אין צורך לייצג את המקף ,’9…’ ,’2’,’1’,’0‘ וים:ומדובר בת

וים.ות 10ישנם בסה"כ סיביות באופן הבא: 4 –ניתן לקודד מחדש כל תו ב

‘0’ 0000 ‘1’ 0001 ‘2’ 0010 ‘3’ 0011 ‘4’ 0100 ‘5’ 0101 ‘6’ 0110 ‘7’ 0111 ‘8’ 1000 ‘9’ 1001

.Short_client קידוד זה מאפשר לשמור את המידע הרצוי במבנה החדש

ומבצעת את הפעולות הבאות: nכתוב פונקציה המקבלת מספר א.

Client רשומות מסוג nמי של אהקצאת מערך דינ .1

קליטת נתונים לתוך אברי המערך. .2

תוך שחרור Short_client מי של רשומות מסוגאמערך למערך דינדחיסת הנתונים ב .3 המערך הישן.

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

ים.ותו 9ת.ז. כמחרוזת של מספר הפונקציה מקבלת .1 הדחוסההעבר אותו לצורה .2הפונקציה להחזיר את המחרוזת . כאשר החיפוש מצליח, על דחוסחפש אותו בלולאה במערך ה .3

NULL.)דחוסהת הינה בצורה המקורית ולא ההמציינת מהו מספר הטלפון של הלקוח. (המחרוז אחרת.

כתוב תוכנית המאפשרת ביצוע הפעולות הנ"ל

Page 27: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 27 -

2שאלה

:ארגומנטים 4 שמקבלת תכנית כתבו .מבתים המורכב בינארי קובץ של שם המהווה מחרוזת הינו הראשון הארגומנט

. 8 להיות חייב שסכומם מספרים הינם) x,y,z(להלן והרביעי השלישי השני הארגומנטים ביטים x -ב המקודד מספר ישנו בית בכל :הבא באופן בביטים המקודד מידע מכיל הקובץ כי נתון

.האחרונים ביטים z -ב המקודד ומספר ,שאחריהם ביטים y -ב המקודד מספר ,השמאליים

x=4,y=3,z=1 כי נניח :לדוגמא )לימין משמאל ( כדלהלן הוא שלהם הבינארי הייצוג אשר בתים 3 ישנם ובקובץ

1010��� 000� 1� 0101011000100101

הרווחים הם רק להמחשת החלוקה לבתים. 10 0 1המספרים המקודדים בבית הראשון הינם: 5 3 0המספרים המקודדים בבית הראשון הינם: 2 2 1המספרים המקודדים בבית הראשון הינם:

:frequencyושכיחותו numberכעת, נתונה הגדרה עבור מספר

typedef struct

{

int number;

int frequency;

} Num_and_Freq;

ים:- Num_and_Freqן, נתונה ההגדרה הבאה לייצוג רשימה מקושרת של כ-כמו

typedef struct listNode{

Num_and_Freq data;

struct listNode* next;

} ListNode;

typedef struct list

{

ListNode* head;

ListNode* tail;

} List;

מהמספרים שהופיעו בקובץ הקלט. למשל, בדוגמא הקודמת תהמורכב רשימה מקושרתהתכנית לייצר על סך הכל היו המספרים הבאים:

פעם אחת – 10

מייםפע – 0 פעמיים – 1 פעם אחת – 5 פעם אחת – 3 פעמיים – 2

פיע בקובץ (בדוגמא זהו המספר הראשון יכיל את המספר הראשון שהוהתא , תאים 6 יהיו רשימהלכן ב ) וכן הלאה.10

Page 28: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 28 -

3שאלה

.אהוא לכל השוניםמספר התווים . נתון שבמחרוזת 8הינו כפולה של n-כך ש nנתונה מחרוזת באורך

.3/8ביחס של לצמצם את המקום הנדרש ביטים לייצג כל תו ניתן 3כיוון שמספיקים .8היותר

שמונה ווצגיישלושה בתים בכלבאופן זה ביטים). 3( 7 -ל 0מספר בין יותאםלכל תו : הצמצוםאופן במקום שלושה בלבד. תווים

מהמחרוזת המקורית, מסודרים לפי סדר השוניםבסדרת התווים ןמנת להתאים את המספרים, נעיי-על

).0 - הערך שיוצמד לכל תו יהיה מיקומו בסדרה זו (החל מוהופעתם הראשונה,

"aaaccbac":: אם המחרוזת המקורית היא: לדוגמא

.0, יוצמד הערך a -ל .1, יוצמד הערך c -ל .2, יוצמד הערך b -ל

המחרוזת המצומצמת תהיה: ו

000 000 000 001 001 010 000 001 הרווחים בין הספרות נועדו להמחשת הייצוג של כל תו.

ם התחתונים מסמלים את הבתים השונים.יהקוו

הפונקציה:ממשו ראשית את char* getUniqueLetters(char* text, int* size);

מסודרים , text -המופיעים ב השוניםומחזירה מערך המכיל את התווים , text המקבלת מחרוזת

, את גודלו של size הפונקציה גם מעדכנת במשתנה. textבמחרוזת במערך לפי סדר הופעתם המערך המוחזר.

, היא תחזיר את המערך:"text="mullyllum: אם תופעל הפונקציה עם למשל

['m', 'u', 'l', 'y'] , שלותעדכן בכתובת size 4את הערך.

).'0\' -: הערך המוחזר של הפונקציה הוא מערך של תווים, ולא מחרוזת (לא מסתיים בשימו לב

. אורכה כתבו תוכנית המקבלת כפרמטר שם של קובץ טקסט. ידוע שהקובץ הנ"ל מורכב משורותכעת, תווים שונים. 8בכל שורה יש לכל היותר ו 8-של כל שורה מתחלק ב

:הבנוי לפי הפורמט הבא התוכנית להמיר קובץ זה לקובץ בינאריעל

:בקובץ הטקסט, ישמרו בקובץ הבינארי הנתונים הבאיםעבור כל שורה

בשורה. השוניםהמייצג את מספר התווים – unsigned charמספר מטיפוס .1

מסודרים , סדרת התווים השונים בשורההמכיל את –ים - charרצף (באורך זה) של .2 לפי סדר הופעתם הראשונה באותה שורה.

המייצג את מספר הבתים בהם נשמרים התווים – unsigned intמספר מטיפוס .3 של השורה. המכווצים

של השורה. הכווץרצף (באורך זה) של בתים המכילים את .4

בסוף. "rds."שמו של הקובץ המיוצר הוא כשמו של קובץ הקלט, בתוספת

לדוגמא:

Page 29: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 29 -

המכיל את שתי השורות:, הוא קובץ טקסט "stam.txt" - נניח ש

התכנית תייצר את, "stam.txt"אם תועבר לתוכנית, כפרמטר בשורת ההפעלה, המחרוזת . קובץ זה יכיל:"stam.txt.rds"הקובץ

3

'a'

'b'

'c'

3

00000101

00000010

01010000

2

'm'

'b'

3

00000100

10000010

00000001

.ב , למחרוזת רגילה.שוניםתווים 8כעת נרצה לשחזר מחרוזת מכווצת המכילה לכל היותר

ביטים. 3תווים מהמחרוזת הרגילה. כל תו תופס מונהש ייצגיםמבמחרוזת המכווצת בתים 3כל

מופיע כל תו כאשר המכיל את כל התווים השונים של המחרוזת, codeאת השחזור נבצע בעזרת מערך בדיוק פעם אחת.

.codeביטים המייצגים את המיקום של אותו תו במערך 3במחרוזת המכווצת במקום כל תו שומרים למשל אם המחרוזת המכווצת היא:

000001001000001000000001 code = ['x','o']והמערך

."xooxoxxo"אזי המחרוזת המשוחזרת תהיה:

בצורה מכווצתמחרוזות השומר rds.עם סיומת כתבו תוכנית המקבלת כפרמטר שם של קובץ בינארי הנתון בסעיף א'.פורמט בהתאם ל

על התוכנית להמיר קובץ זה לקובץ טקסט. שמו של הקובץ המיוצר הוא כשמו של קובץ הקלט, rds.ללא הסיומת

acbaccba

mbbmbmmb

Page 30: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 30 -

4שאלה . על מנת לפענח אותו יש לשנות את מיקום הביטים בו. השינוי יעשה בעזרתchנתון תו מוצפן א.

. תהליך הפענוח יעשה באופן הבא:0-7של המספרים [a0, a1, …, a7]תמורה

בתו המפוענח. a0 -נשים בביט שנמצא במקום ה chאת הביט האפס של התו •

בתו המפוענח. a1 -נשים בביט שנמצא במקום ה chאת הביט האחד של התו •

וכך הלאה... •

.least significant bit (lsb)-הוא הביט הימני ביותר כלומר ה 0 - : הביט ההערה חשובה

[3,2,1,0,7,6,5,4]בעזרת התמורה: 00110001למשל אם נרצה לפענח את התו שמיוצג בינארית:

) עבר 1(למשל הביט האפס של התו המקורי ( 11001000נקבל את התו המפוענח שמיוצג בינארית: בתו המפוענח, וכו'). 3 -לביט ה

;char decode(char ch, int* key) כתבו את הפונקציה:

. 0-7המכיל תמורה כלשהי של המספרים 8גודל ב key ומערך ,ch הפונקציה מקבלת תו מוצפן

עפ"י השיטה שתוארה לעיל, ותחזיר את התו המפוענח., ch ציה תפענח את התוהפונק

בפונקציה מסעיף א' על מנת לכתוב את הפונקציה: והשתמש ב.

char* decodeString(char* name, int* key);

המכיל תמורה כלשהי של 8בגודל key המכילה שם מקודד, ומערך name הפונקציה מקבלת מחרוזתשתכיל את השם המפוענח. פענוח השם יתבצע חדשה. הפונקציה תיצור ותחזיר מחרוזת 0-7המספרים

. key עפ"י התמורה nameע"י פענוח כל אחד מתווי

שירות הביטחון הכללי שומר שני קבצים עבור כל פעולה שהוא מבצע. ג.שמות של הסוכנים מוצפנת) המחזיק בצורה mail - לשלוח ב . קובץ בינארי (שאותו ניתן אפילו1

המשתתפים במבצע. . קובץ טקסט (שנשמר בכספת) המכיל את התמורות שבעזרתן ניתן לפענח את השמות המקודדים 2

בקובץ הבינארי.

פורמט קובץ השמות המקודדים (הקובץ הבינארי): ופן הבא:שמות הסוכנים נשמרים ברצף. כל שם (מקודד) נשמר בא

המייצג את אורך שמו של הסוכן ואחריו רצף באורך זה של תווים מוצפנים (short int)מספר שלם המרכיבים יחד את שמו.

פורמט קובץ המפתחות (קובץ הטקסט): המופרדים ברווחים. 0-7הקובץ מורכב משורות. בכל שורה תופיע תמורה של המספרים

נשמרו השמות המקודדים בקובץ השמות. בפרט מספר השורות הוא סדר השורות בקובץ מתאים לסדר בו כמספר הסוכנים בקובץ השמות.

בהינתן ההגדרה הבאה למבנה עבור רשימה מקושרת:

typedef struct l_node{

char* name;

struct l_node * next;

}L_NODE;

typedef struct list{

L_NODE* head;

L_NODE* tail;

}LIST;

בו את הפונקציה:כתLIST decodeMission(FILE* agents, FILE* keys);

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

• agents - .קובץ בינארי המכיל שמות מקודדים של סוכנים בפורמט שתואר לעיל

• keys - .קובץ טקסט המכיל מפתחות בפורמט שתואר לעיל

Page 31: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 31 -

. על agentsהפונקציה תחזיר רשימה, שתכיל את שמותיהם המפוענחים של הסוכנים המופיעים בקובץ הרשימה להכיל את הסוכנים לפי סדר הופעתם בקובץ.

5שאלה א. כתבו את הפונקציה:

int* filter(int* Numbers, int size, unsigned char* pred,

int* new_size);

היא ,. כמו כןsizeמספרים שלמים שונים זה מזה, ואת גודלו שלNumbers הפונקציה מקבלת מערך

8של ביטים, בגודל predמקבלת מערך size בתים. כל ביט במערךpred מייצג נתון אחד של ,

, באופן הבא:Numbersהמערך

.Numbersבמערך 0, מייצג את הנתון באינדקס predשל המערך 0 -בבית ה 0 -הביט ה

.Numbersבמערך 1, מייצג את הנתון באינדקס predשל המערך 0 -בבית ה 1 -הביט ה

M .Numbersבמערך 8, מייצג את הנתון באינדקס predשל המערך 1 -בבית ה 0 -הביט ה

וכך הלאה.

, אשר הביט Numbersהפונקציה תייצר ותחזיר את תת המערך המכיל אך ורק את הנתונים מהמערך

. 1, הוא predהמתאים להם במערך

את גודלו של תת המערך שייצרה. new_sizeכמו כן, הפונקציה תעדכן במשתנה הפלט

, מוגדרים באופן הבא:pred -ו Numbersלמשל, אם המערכים

, תייצר את המערך: filter(Numbers, pred, 16, size)הקריאה

. 5את הערך new_sizeוכן תעדכן במשתנה אליו מצביע

: הערות

.8 -, מתחלק בNumbers, מספר הנתונים במערך size -הניחו ש •

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

השתמשו בפונקציה מסעיף א', על מנת לכתוב הפונקציה הבאה: ב.

int* xorFilter(int* Numbers, int size, unsigned char* pred1,

unsigned char* pred2, int* new_size);

. כמו כן היא sizeמספרים שלמים שונים זה מזה, ואת גודלו שלNumbers הפונקציה מקבלת מערך

8של ביטים, כל אחד מהם בגודל pred2 - ו pred1מקבלת שני מערכים size ,בתים. כל אחד מהביטים

, לפי ההתאמה שתוארה Numbers, מייצג נתון מסוים של המערך pred2 - ו pred1בכל אחד מהמערכים

בסעיף א'.

8 6 22 10 18

8 4 2 6 30 22 28 32 20 26 24 10 16 14 18 12

Numbers

0 1 0 0 1 0 0 0

0 0 1 0 1 0 0 1 pred

Page 32: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 32 -

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

. 1, הוא pred2 - , וpred1הביטים המתאימים לו במערך ןמבי בדיוק אחדיופיע במערך התוצאה אם"ם

ייצרה.את גודלו של תת המערך ש new_sizeכמו כן, הפונקציה תעדכן במשתנה הפלט

.8 - , מתחלק בNumbers, מספר הנתונים במערך size -: הניחו שהערה

Page 33: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 33 -

פויינטרים לפונקציות

1שאלה כתבו את הפונקציה:

void* scramble(void* arr, int ElemSize, int n, int* indArr);

הפונקציה מקבלת:

• arr - .מערך של איברים מטיפוס כלשהו

• ElemSize - גודל של כל אלמנט במערךarr

• n - מספר האיברים במערךarr.

• indArr - :0,1מערך המכיל תמורה של המספרים, , ( 1)n −K.

באופן הבא: indArrשבו סדר האיברים נקבע על פי המערך חדשעל הפונקציה ליצור מערך

.indArr[i]במערך החדש יהיה האיבר שהאינדקס שלו במערך הישן הוא i - האיבר ה

3nלמשל, אם indArr[2,0,1] -ו = אז: =

. arrשל 2 -של המערך החדש ימצא האיבר מהמקום ה 0 -במקום ה

. arrשל 0 -של המערך החדש ימצא האיבר מהמקום ה 1 -במקום ה

. arrשל 1 -של המערך החדש ימצא האיבר מהמקום ה 2 -במקום ה

2שאלה במערך:נתון האלגוריתם הבא למימוש חיפוש בינארי של נתון

.Arr –קלט: מערך של נתונים

Size -גודל המערך

.Item –נתון לחיפוש

).Arrמופיע במערך Itemאם"ם ( (true) פלט:

1 . found �false

2 .left � 0

3 .right � (Size-1)

) . כל עוד (4

4.1 place �( (left+right) div 2)

)Arr[place]=Itemאם ( 4.2

4.2.1 found � true

)Arr[place]<Itemאחרת אם ( 4.3

4.3.1 left � (place+1)

אחרת 4.4

4.4.1 right� (place-1)

found. החזר את 5

∧ ≤! ( )found left right

Page 34: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 34 -

הפונקציה הבאה:א. כתבו את int binSearch(void* Arr, int Size, int ElemSize,

void* Item, int (*compare)(void*, void*));

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

int- :ים וכו'). הפונקציה מקבלת

• Arr - .כתובת התחלה של מערך

• Size - .מספר הנתונים בו

• ElemSize - .מספר הבתים שתופס כל אחד מהנתונים

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

• compare - .(מהטיפוס של הנתונים מהמערך) פויינטר לפונקציה המשווה בין שני נתונים

אחרת. 0שווה לאחד מנתוני המערך, או Itemאם הנתון עליו מצביע 1החזיר את הערך על הפונקציה ל

:הערה

, מקבלת כתובות של שני נתונים אותם היא משווה. ומחזירה:compareהניחו שהפונקציה

אם שני הפרמטרים מצביעים על נתונים שווים. -אפס •

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

אם הפרמטר הראשון מצביע על נתון גדול יותר מהנתון שמוצבע ע"י הפרמטר - מספר חיובי • השני.

,שכתבתם, על מנת לכתוב את הפונקציה:BinSearch השתמשו בפונקציהב. int stringBinSearch(char** strings, int size, char* str);

, ומחרוזתsizeשל מחרוזות ממוינות בסדר לקסיקוגרפי, את גודלו stringsהמקבלת מערך

.strנוספת

אחרת. 0, או stringsמופיעה במערך strאם המחרוזת 1על הפונקציה להחזיר את הערך

הוא המערך: stringsלמשל אם

.1תחזיר stringBinSearch(strings,4,"good-luck")אז ההפעלה:

“abcdefg”

"good-luck"

"mully"

"stam"

Page 35: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 35 -

3שאלה מאגר של נתונים על מוצרים נשמר בקובץ בינארי. הקובץ בנוי בפורמט הבא:

.N -, המייצג את מספר המוצרים בקובץ. נסמן את ערכו בintמספר מטיפוס .1

של נתונים של מוצרים. כל מוצר מופיע בקובץ בפורמט הבא: Nרצף באורך .2

.len -, המייצג את מספר התווים בשמו של המוצר. נסמן את ערכו בintמספר מטיפוס •

בסופו). '0\'תווים, המכיל את שמו של המוצר (ללא lenרצף של •

, המייצג את מחירו של המוצר.intמספר מטיפוס •

נרצה לייצר שני קבצי אינדקס לקובץ המאגר הנ"ל:

(מהקטן לגדול). ממוינים לפי שם המוצר) למוצרים בקובץ המאגר, offsetsמכיל את ההיסטים ( •

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

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

בסעיף א' של השאלה נגדיר את הפונקציה הכללית ליצירת קובץ אינדקס ממוין, ובסעיף ב' נייצר את שני קבצי האינדקס הרצויים לנו.

א. כתבו את הפונקציה: void createSortedIndex(char* DB_Name, char* IndexFileName,

int (*compare) (void*, void*));

המכילה את שמו של קובץ בינארי. הקובץ מכיל מאגר של נתוני DB_Nameהפונקציה מקבלת מחרוזת מוצרים (לא ממוינים) בפורמט שהוגדר לעיל.

, המכיל רצף של נתונים מטיפוסIndexFileNameהפונקציה מייצרת קובץ אינדקסים, בשם

long int) כל נתון בקובץ האינדקס, מייצג היסט מתחילת קובץ המאגר ,DB_Name לתחילת נתוניו ( של מוצר מסוים.

אם נעבור על קובץ המאגר, לפי רצף ההיסטים בקובץ האינדקסים, המיוצר ע"י הפונקציה, נקבל את נתוני

.compareהמאגר ממוינים מהקטן לגדול, עפ"י הסדר המושרה מפונקצית ההשוואה

לשני נתונים ומשווה מצביעיםהינה פונקצית השוואה כללית, המקבלת compare: הפונקציה הערה פונקציה משרה סדר באופן הבא: ביניהם. ה

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

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

שעליו מצביע הפרמטר השני, היא תחזיר את לזה שווהאם הנתון עליו מצביע הפרמטר הראשון • . 0הערך

ממשו (בין היתר) את הפונקציה:, createSortedIndexלצורך כתיבת הפונקציה void sort(void* Arr, int elem_size, int num_elems,

int (*compare) (void*, void*));

המייצג את גודלו של כל elem_sizeלתחילת מערך, מספר שלם Arrמקבלת מצביע sortהפונקציה

המייצג את מספר הנתונים במערך. num_elemsנתון במערך, ומספר שלם נוסף

, עפ"י הסדר המושרה מפונקצית ההשוואה הכללית Arrהפונקציה ממיינת את הנתונים במערך

compare.

Page 36: םדקתמ תונכת C תפשב - האקדמיתhbinsky/c content/Exercises ver 2.pdf- 5 - . 8x^4 + 7x^3 - 5x - 8 : סיפדהל שי 8 7 5 8x x x4 3+ − − : םונילופה תא

- 36 -

ת לכתוב את שתי הפונקציות הבאות:, על מנהשתמשו בפונקציה שכתבתם בסעיף א' ב.

void indexSortedByName(char* DB_Name, char* IndexFileName);

void indexSortedByPrice(char* DB_Name, char* IndexFileName);

המכיל מאגר של נתונים על מוצרים, בפורמט DB_Nameכל אחת מהפונקציות מקבלת שם של קובץ

(לפי indexFileNameשפורט בתחילת השאלה. כל אחת מהפונקציות מייצרת קובץ אינדקסים בשם הפורמט שהוגדר בסעיף א').

אם נעבור על קובץ המאגר, לפי רצף ההיסטים בקובץ אשר מייצרת הפונקציה הראשונה, נקבל את נתוני ם המוצרים, מהקטן לגדול.המאגר ממוינים לפי ש

אם נעבור על קובץ המאגר, לפי רצף ההיסטים בקובץ אשר מייצרת הפונקציה השנייה, נקבל את נתוני המאגר ממוינים לפי מחיר המוצרים, מהקטן לגדול.