1 שאלה

‫תרגילי נוספי‪+‬פתרונות – לחלק א )עיצוב תוכנה מבוסס עצמי(‬
‫שאלה ‪1‬‬
‫על התלמידי בכיתה הוטלה המשימה לממש פעולה נוספת במחלקה ‪ List‬שכותרתה‪:‬‬
‫)(‪public void secretList‬‬
‫לפני שני פתרונות למשימה כפי שנכתבו על ידי שני תלמידי שוני‪:‬‬
‫הפתרו של רינה‪:‬‬
‫)(‪public void secretList‬‬
‫{‬
‫;‪Node pos = this.head‬‬
‫)‪while(pos != null‬‬
‫{‬
‫;))(‪this.insert(null,pos.getInfo‬‬
‫;)‪pos = this.remove(pos‬‬
‫}‬
‫}‬
‫הפתרו של משה‪:‬‬
‫)(‪public void secretList‬‬
‫{‬
‫;‪Node pos1 = this.head‬‬
‫;‪Node pos2 = null‬‬
‫;‪Node pos3 = null‬‬
‫)‪while(pos1 != null‬‬
‫{‬
‫;)(‪pos2 = pos1.getNext‬‬
‫;)‪pos1.setNext(pos3‬‬
‫;‪pos3 = pos1‬‬
‫;‪pos1 = pos2‬‬
‫}‬
‫;‪this.head = pos3‬‬
‫}‬
‫א‪.‬‬
‫עקוב אחר הפיתרו של רינה עבור הרשימה‪) 3,25,6,0,15,4 :‬משמאל לימי(‪ .‬מה התקבל?‬
‫רשו את טענת היציאה של הפעולה ‪ secretList‬שכתבה רינה‪.‬‬
‫ב‪.‬‬
‫עקוב אחר הפיתרו של משה עבור אותה רשימה‪ .‬מה התקבל?‬
‫הא שני הפתרונות מבצעי אותה פעולה‪ ,‬הסבר‪.‬‬
‫ג‪.‬‬
‫המורה הציגה לתלמידי אלגורית הפותר את המשימה באופ הבא‪:‬‬
‫‪1‬‬
‫רשימהסודית‬
‫בנה מחסנית‬
‫עב ר על הרשימה הנוכחית מתחילתה‬
‫עב!ר כל חוליה‪ ,‬דחו" למחסנית את ער החוליה‬
‫עב ר על כל הרשימה הנוכחית מתחילתה‬
‫לכל חוליה ברשימה‪ ,‬שלו" ער מהמחסנית ועדכ את ער החוליה בער שנשל"‬
‫מהמחסנית‪.‬‬
‫ממש את האלגורית רשימהסודית כפעולה פנימית של המחלקה ‪.List‬‬
‫שאלה ‪2‬‬
‫חברת ‪ Helpline‬מחזיקה ‪ 20‬עמדות תמיכה טלפוניות הממוספרות ‪.19&0‬‬
‫שירות התמיכה מתנהל באופ הבא‪:‬‬
‫• כל מתקשר משאיר את שמו ואת מספר הטלפו שלו למוקד‪.‬‬
‫• המוקד מצר" את פרטי המתקשר לאוס" הממתיני בעמדת התמיכה הכי פחות עמוסה‪.‬‬
‫מ!צאי מאוס" הממתיני של העמדה‪.‬‬
‫• כאשר עמדת התמיכה מטפלת במתקשר‪ ,‬פרטיו ָ‬
‫בחברה הוחלט להקי מערכת ממוחשבת לטיפול בלקוחות‪.‬‬
‫לפני ממשק חלקי של המחלקה ‪) Caller‬מתקשר(‪:‬‬
‫הפעולה בונה מתקשר חדש ששמו ‪ name‬ומספר‬
‫)‪Caller (String name, String phone‬‬
‫הטלפו שלו ‪phone‬‬
‫מחזירה ש של מתקשר‬
‫) (‪String getName‬‬
‫מחזירה מספר טלפו של מתקשר‬
‫) (‪String getPhone‬‬
‫לפני ממשק חלקי של המחלקה ‪) Post‬עמדה(‪:‬‬
‫מחזירה את מספר הממתיני בעמדה‬
‫) (‪int lineLength‬‬
‫מחזירה את המתקשר הראשו מבי הממתיני‬
‫בעמדה‪ ,‬ומוחקת את נתוניו מאוס" הממתיני‪ .‬א‬
‫) (‪Caller callBack‬‬
‫אי ממתיני בעמדה‪ ,‬יוחזר ‪null‬‬
‫מוסיפה מתקשר ‪ c‬לאוס" הממתיני בעמדה‬
‫)‪void addToPost (Caller c‬‬
‫א‪ .‬ייצג את המחלקה ‪.Post‬‬
‫ב‪ .‬ממש את הפעולה ) (‪.Caller callBack‬‬
‫ג‪.‬‬
‫ממש את הפעולה )‪.addToPost (Caller c‬‬
‫‪2‬‬
‫ד‪ .‬ניהול כל העמדות נעשה בעזרת המחלקה ‪) Support‬ניהול עמדות תמיכה(‪ .‬ייצג את‬
‫המחלקה ‪.Support‬‬
‫ה‪ .‬ממש את הפעולה הבאה מתו ממשק המחלקה ‪:Support‬‬
‫מקבלת מתקשר ‪ c‬ומוסיפה אותו לסו" אוס"‬
‫)‪void positionCaller (Caller c‬‬
‫הממתיני של העמדה שמספר הממתיני בה‬
‫הוא הנמו ביותר‪ .‬א יש כמה עמדות כאלה‪,‬‬
‫המתקשר ‪ c‬יתווס" לראשונה מביניה‬
‫שאלה ‪3‬‬
‫רשימה מעגלית ‪ CircularList‬היא רשימה שבה החוליה האחרונה מכילה הפנייה אל החוליה‬
‫הראשונה ברשימה כ שהרשימה מהווה מעי "מעגל"‪ .‬כאשר יש ברשימה רק חוליה אחת‪ ,‬העוקב‬
‫שלה פונה אליה עצמה‪.‬‬
‫‪CircularList‬‬
‫‪first‬‬
‫לפני ייצוג הרשימה המעגלית כאשר התכונה היחידה ברשימה היא הפנייה לאיבר ה"ראשו"‬
‫שבה‪ .‬ממשק החוליה הוא הממשק המופיע בעמוד ‪ 27‬בחוברת‪ ,‬הער השמור בחוליה הוא‬
‫מחרוזתי‪.‬‬
‫{‪public class CircularList‬‬
‫;‪private Node first‬‬
‫}‬
‫לפני ממשק חלקי של רשימה מעגלית שערכי החוליות שלה ה מחרוזות‪:‬‬
‫הפעולה בונה רשימה מעגלית ריקה‬
‫)(‪CircularList‬‬
‫מחזירה את המקו של החוליה הראשונה ברשימה‬
‫הנוכחית‪ .‬א הרשימה ריקה‪ ,‬הפעולה תחזיר ‪null‬‬
‫מכניסה לרשימה הנוכחית את האיבר ‪ x‬מקו אחד אחרי‬
‫המקו ‪ .p‬הפעולה מחזירה את המקו של החוליה‬
‫החדשה שהוכנסה‪.‬‬
‫על מנת להכניס חוליה ראשונה לרשימה מעגלית ריקה יש‬
‫לשלוח ‪ null‬כפרמטר המקו‪.‬‬
‫הנחה‪ p :‬הוא מקו קיי ברשימה הנוכחית‬
‫מוציאה מהרשימה הנוכחית את האיבר הנמצא בה במקו‬
‫‪ .p‬מחזירה את המקו העוקב ל& ‪ .p‬א לאחר ההוצאה‬
‫הרשימה התרוקנה‪ ,‬יוחזר ‪.null‬‬
‫הנחות‪ :‬הרשימה אינה ריקה‪ p .‬הוא מקו קיי )שאינו‬
‫‪ (null‬ברשימה הנוכחית‬
‫‪3‬‬
‫)(‪Node getFirst‬‬
‫)‪Node insert (Node p, String x‬‬
‫)‪Node remove (Node p‬‬
‫מחזירה 'אמת' א הרשימה הנוכחית ריקה‪ ,‬ו'שקר' אחרת‬
‫)(‪boolean isEmpty‬‬
‫א‪ .‬ממש את הפעולה )‪ Node remove (Node p‬המופיעה בממשק הרשימה המעגלית‪.‬‬
‫ב‪ .‬כשבאו חבריו של משה לשחק במשחק המחשב החדש שקיבל‪ ,‬החליטו לקבוע סדר בי‬
‫החברי כדי למנוע מריבות‪ .‬ה התיישבו במעגל ובחרו מספר ‪ .r‬משה התחיל לספור ‪r‬‬
‫ילדי החל מהילד הראשו במעגל‪ .‬כאשר הגיע אליו‪ ,‬יצא הילד מהמעגל והחל לשחק‬
‫במחשב‪ .‬הספירה של ‪ r‬ילדי המשיכה מהמקו הבא במעגל‪ ,‬והילד הבא שיצא מהמעגל‬
‫ידע שהוא הבא לשחק במחשב‪ .‬כ המשיכו במניית הילדי והוצאת מהמעגל‪ ,‬עד‬
‫שהמעגל התרוק ונקבע סדר המשחק לשביעות רצו כול‪.‬‬
‫ממש את הפעולה‪:‬‬
‫)‪public static List playGame (CircularList lst, int r‬‬
‫המקבלת רשימה מעגלית ובה שמות הילדי ומספר חיובי ‪ r‬ומחזירה רשימה שאינה‬
‫מעגלית של מחרוזות‪ ,‬הכוללת את כל שמות הילדי לפי הסדר שבו ישחקו במחשב‪.‬‬
‫שאלה ‪4‬‬
‫ע‪" -‬פירמידה" בגובה ‪ h‬הוא ע‪ -‬בינרי מלא המכיל מספרי שלמי‪ ,‬כ שער כל צומת בע‪ -‬הוא‬
‫גובהו‪ .‬לכ‪:‬‬
‫•‬
‫ע‪" -‬פירמידה" בגובה ‪ 0‬הוא ע‪ -‬עלה שער שורשו הוא ‪.0‬‬
‫•‬
‫ע‪" -‬פירמידה" בגובה ‪ 1‬הוא ע‪ -‬הבנוי משורש שערכו ‪ 1‬וער כל אחד משני בניו הוא ‪.0‬‬
‫•‬
‫ע‪" -‬פירמידה" בגובה ‪) h‬עבור ‪ (h > 1‬הוא ע‪ -‬בינרי המורכב משורש שערכו ‪ h‬ומשני תת&‬
‫עצי שכל אחד מה הוא ע‪" -‬פירמידה" בגובה ‪. h&1‬‬
‫א‪ .‬צייר ע‪" -‬פירמידה" בגובה ‪.3‬‬
‫ב‪ .‬ממש את הפעולה הבאה‪ ,‬המקבלת מספר של אי&שלילי ‪ h‬ומחזירה ע‪" -‬פירמידה" בגובה ‪.h‬‬
‫)‪public static Tree buildPyramidTree (int h‬‬
‫ג‪ .‬ממש את הפעולה הבאה‪ ,‬המקבלת ע‪ -‬בינרי ‪ ,(tree != null) tree‬ומספר של אי&שלילי ‪,h‬‬
‫ומחזירה 'אמת' א הע‪ -‬הוא ע‪" -‬פירמידה" בגובה ‪ ,h‬ו&'שקר' אחרת‪.‬‬
‫)‪public static boolean isPyramidTree (Tree tree, int h‬‬
‫‪4‬‬
‫שאלה ‪5‬‬
‫ע‪" -‬מתכונת" הוא ע‪ -‬בינרי המכיל מספרי שלמי‪ ,‬כאשר‪:‬‬
‫•‬
‫ער השורש שלו קט מער כל אחד מבניו‬
‫•‬
‫כל תת ע‪ -‬הוא ע‪" -‬מתכונת"‬
‫א‪ .‬אילו מהעצי הבינריי הבאי ה עצי "מתכונת"‪:‬‬
‫‪2‬‬
‫‪4‬‬
‫‪9‬‬
‫‪4‬‬
‫‪8‬‬
‫‪15‬‬
‫‪5‬‬
‫‪16‬‬
‫‪18‬‬
‫‪15‬‬
‫‪1‬‬
‫ע ‪1‬‬
‫‪6‬‬
‫‪10‬‬
‫‪94‬‬
‫‪6‬‬
‫‪15‬‬
‫‪70‬‬
‫ע ‪2‬‬
‫‪94‬‬
‫‪18‬‬
‫‪8‬‬
‫ע ‪3‬‬
‫ב‪ .‬איפה נמצא הער הקט ביותר והגדול ביותר בע‪ ?-‬נמק תשובת‪.‬‬
‫ג‪ .‬ממש את הפעולה הבאה‪:‬‬
‫)‪public static boolean isMatkonetTree (Tree tree‬‬
‫הפעולה מקבלת ע‪ -‬בינרי ‪ ,(tree != null) tree‬ומחזירה 'אמת' א הע‪ -‬הוא ע‪" -‬מתכונת"‬
‫ו&'שקר' אחרת‪.‬‬
‫ד‪ .‬כתוב פעולה חיצונית‪ ,‬יעילה ככל האפשר‪ ,‬שתקבל ע‪" -‬מתכונת" ‪ myTree‬וער נוס" ‪,x‬‬
‫ותדפיס את ערכי כל הצמתי בע‪ t -‬שערכ קט מ& ‪.(myTree != null) .x‬‬
‫‪5‬‬
‫שאלה ‪6‬‬
‫רשימה מעגלית דוכיוונית ‪ CircleDoubleList‬היא רשימה מקושרת‪ ,‬בה כל חוליה מכילה‬
‫הפנייה לחוליה הקודמת לה ברשימה בנוס להפנייה לחוליה העוקבת לה‪ .‬החוליה האחרונה‬
‫מכילה הפנייה ל"חוליה הבאה" שהיא החוליה הראשונה ברשימה‪ .‬החוליה הראשונה מפנה אל‬
‫החוליה "הקודמת לה" שהיא החוליה האחרונה ברשימה‪.‬‬
‫‪CircleDoubleList‬‬
‫‪head‬‬
‫לפני ייצוג חוליה ‪ DoubleNode‬שערכה ‪ int‬ברשימה מעגלית דו&כיוונית‪:‬‬
‫{‪public class DoubleNode‬‬
‫;‪private int info‬‬
‫;‪private DoubleNode next‬‬
‫הפנייה לאיבר הקוד ‪//‬‬
‫;‪private DoubleNode prev‬‬
‫}‬
‫הנח כי במחלקה ‪ DoubleNode‬קיימות פעולות ‪ get‬ו&‪ set‬עבור כל התכונות וכי הפעולה הבונה שלה‬
‫נראית כ‪:‬‬
‫{)‪public DoubleNode (int info‬‬
‫;‪this.info = info‬‬
‫;‪this.next = null‬‬
‫;‪this,prev = null‬‬
‫}‬
‫לפני ייצוג של רשימה מעגלית דוכיוונית ומימוש הפעולה הבונה רשימה מעגלית דוכיוונית‬
‫ריקה‪.‬‬
‫{ ‪public class CircleDoubleList‬‬
‫;‪private DoubleNode head‬‬
‫{)( ‪public CircleDoubleList‬‬
‫;‪this.head = null‬‬
‫}‬
‫}‬
‫‪6‬‬
‫א‪ .‬ממש את הפעולה הבאה בממשק הרשימה המעגלית הדו&כיוונית‪:‬‬
‫מכניסה לרשימה הנוכחית את האיבר ‪info‬‬
‫מקו אחד אחרי המקו ‪ .p‬הפעולה מחזירה‬
‫את המקו של החוליה החדשה שהוכנסה‪.‬‬
‫כאשר מכניסי איבר ראשו לרשימה ריקה‪,‬‬
‫המקו ‪ p‬הוא ‪.null‬‬
‫הנחה‪ p :‬הוא מקו קיי ברשימה הנוכחית‬
‫)‪DoubleNode insert (DoubleNode p, int info‬‬
‫ב‪ .‬נתו תור‪ ,‬המיוצג באמצעות רשימה מעגלית‪:‬‬
‫{‪public class Queue‬‬
‫;‪CircleDoubleList list‬‬
‫}‬
‫ממש את פעולת ההוצאה מתור זה‪.‬‬
‫שאלה ‪7‬‬
‫במעונות הסטודנטי יש בני ב ‪ 10‬קומות ו&‪ 30‬דירות בכל קומה‪) .‬הערה‪ :‬קומת הכניסה‪,‬קומה ‪,0‬‬
‫לא מכילה דירות אלא שטח ציבורי(‪ .‬לגבי כל דירה שמורי הפרטי הבאי‪ :‬מספר הדירה )מספר‬
‫תלת&ספרתי בו הספרה השמאלית מייצגת את הקומה ‪ ,9&1‬ושתי הספרות הימניות מייצגות את‬
‫מספר הדירה ‪ ,(29&0‬מספר המיטות בדירה‪ ,‬מספר המיטות התפוסות ואת שמות כל הדיירי‬
‫בדירה‪.‬‬
‫א‪.‬‬
‫ייצג את המחלקה ‪) Flat‬דירה(‪.‬‬
‫ב‪.‬‬
‫ממש את הפעולות הבאות מתו ממשק המחלקה ‪:Flat‬‬
‫הפעולה בונה דירה לפי מספר הדירה ‪flatNum‬‬
‫)‪Flat (int flatNum, int numBeds‬‬
‫ומספר המיטות ‪numBeds‬‬
‫מקבלת ש סטודנט ‪ ,name‬ומוסיפה את ש‬
‫)‪boolean addStudent (String name‬‬
‫הסטודנט לשמות הדיירי בדירה‪ ,‬א יש‬
‫מיטה שאינה תפוסה‪ .‬א הפעולה מצליחה‪,‬‬
‫מעדכנת את מספר המיטות התפוסות ומחזירה‬
‫'אמת'‪ ,‬אחרת )א כל המיטות כבר תפוסות(‬
‫מחזירה 'שקר'‬
‫מקבלת ש סטודנט ‪ ,name‬ומחזירה 'אמת'‬
‫)‪boolean livesInFlat (String name‬‬
‫א סטודנט זה מתגורר בדירה‪ ,‬אחרת מחזירה‬
‫'שקר'‬
‫‪7‬‬
‫ג‪.‬‬
‫ייצג את המחלקה ‪) Dorm‬בני מעונות הסטודנטי(‪.‬‬
‫ד‪.‬‬
‫ממש את הפעולות הבאות מתו ממשק המחלקה ‪:Dorm‬‬
‫בונה בני מעונות כ שמספר כל דירה הוא‬
‫)(‪Dorm‬‬
‫בהתא למספר הקומה בבני )‪ (9&1‬ומספר‬
‫הדירה בקומה)‪ .(29&0‬מספר המיטות בדירה‬
‫הוא סכו ספרת האחדות של מספר הדירה‬
‫ומספר הקומה‬
‫מקבלת מספר קומה ‪ ,floor‬ומחזירה מספר‬
‫) ‪int numEmptyBeds (int floor‬‬
‫המיטות הפנויות בכל הדירות בקומה זו‬
‫שאלה ‪8‬‬
‫ע‪" -‬ברוש" הוא ע‪ -‬בינרי המכיל מספרי שלמי‪ ,‬כאשר‪:‬‬
‫•‬
‫ער השורש שלו גדול מסכו ערכי כל צאצאיו בתת ע‪ -‬השמאלי‪ ,‬וקט מסכו ערכי כל‬
‫צאצאיו בתת ע‪ -‬הימני‪.‬‬
‫•‬
‫כל תת ע‪ -‬הוא ע‪" -‬ברוש"‪.‬‬
‫א‪ .‬ציי עבור כל אחד מהעצי הבאי הא הוא ע‪" -‬ברוש" או לא‪ ,‬ונמק‪.‬‬
‫‪70‬‬
‫‪25‬‬
‫‪7‬‬
‫‪14‬‬
‫‪5‬‬
‫‪9‬‬
‫‪50‬‬
‫‪3‬‬
‫‪40‬‬
‫‪15‬‬
‫‪19‬‬
‫‪20‬‬
‫ע ‪1‬‬
‫‪4‬‬
‫‪20‬‬
‫‪16‬‬
‫‪8‬‬
‫ע ‪2‬‬
‫ב‪ .‬הא נית לדעת היכ נמצא הער הגדול ביותר בע‪" -‬ברוש" מבלי לעבור על כל צמתיו? נמק‬
‫את תשובת‪.‬‬
‫ג‪ .‬ממש את הפעולה הבאה‪:‬‬
‫)‪public static boolean isBroshTree (Tree tree‬‬
‫הפעולה מקבלת ע‪ -‬בינרי ‪ ,(tree != null) tree‬ומחזירה 'אמת' א הע‪ -‬הוא ע‪" -‬ברוש"‬
‫ו&'שקר' אחרת‪.‬‬
‫‪8‬‬
‫פתרונות‬
‫פתרו‪ #‬אפשרי לשאלה ‪1‬‬
‫א‪ .‬הרשימה שתתקבל לאחר זימו הפעולה שרינה כתבה היא‪) 4,15,0,6,25,3 :‬משמאל לימי(‪.‬‬
‫טענת היציאה‪ :‬הפעולה הופכת את סדר האיברי ברשימה‪.‬‬
‫ב‪ .‬הרשימה שתתקבל לאחר זימו הפעולה שמשה כתב היא‪) 4,15,0,6,25,3 :‬משמאל לימי(‪.‬‬
‫כ‪ ,‬שני הפתרונות מבצעי אותה פעולה‪ .‬הפעולה שרינה כתבה מוציאה איברי‪ ,‬החל‬
‫מהאיבר השני )א קיי( ומכניסה אות לתחילת הרשימה‪ .‬הפעולה של משה משנה את‬
‫ההפניות של כל איבר ברשימה לאיבר שלפניו )במקו אחריו( – לבסו"‪ ,‬האיבר העוקב‬
‫לאיבר הראשו יהיה ‪ null‬וההפניה ‪ head‬תהיה על האיבר האחרו ברשימה‪.‬‬
‫האיור הבא מתאר מצב ברגע מסוי של ריצת הפעולה שמשה כתב‪:‬‬
‫ג‪ .‬מימוש האלגורית רשימהסודית כפעולה של המחלקה ‪:List‬‬
‫מחסנית של ערכים שלמים‪//‬‬
‫)(‪public void secretList‬‬
‫{‬
‫;)(‪Stack stack = new Stack‬‬
‫;‪Node pos = this.head‬‬
‫)‪while(pos != null‬‬
‫{‬
‫;))(‪stack.push(pos.getInfo‬‬
‫;)(‪pos = pos.getNext‬‬
‫}‬
‫;‪pos = this.head‬‬
‫))(‪while(!stack.isEmpty‬‬
‫{‬
‫;))(‪pos.setInfo(stack.pop‬‬
‫;)(‪pos = pos.getNext‬‬
‫}‬
‫}‬
‫‪9‬‬
‫פתרו‪ #‬אפשרי לשאלה ‪2‬‬
‫ו‪ .‬ייצוג המחלקה ‪.Post‬‬
‫‪public class Post‬‬
‫{‬
‫תור שאיבריו מטיפוס ‪private Queue postQueue; // Caller‬‬
‫מספר הממתינים שנמצאים בעמדה כרגע ‪//‬‬
‫;‪private int numCallers‬‬
‫}‬
‫הסבר‪ :‬העמדה מיוצגת ע"י תור שאיבריו מטיפוס ‪ Caller‬על מנת לשמור על סדר הממתיני‬
‫על פי קבלת‪ .‬בנוס" נשמר מספר המתקשרי הממתיני בעמדה ברגע נתו‪ .‬דבר זה מייעל את‬
‫מציאת העמדה הקצרה בכל שלב שבו זה נדרש‪) .‬נית לייצג את אוס" הממתיני ג בעזרת‬
‫רשימה(‪.‬‬
‫הערה‪ :‬נית להחליט שלא לשמור את מספר הממתיני בעמדה בכל רגע כתכונה של המחלקה‪,‬‬
‫א אז ישתנו המימושי בהמש ויש לבדוק שמתקיימת עקביות בי הייצוג והמימוש‪.‬‬
‫ז‪ .‬נממש את הפעולה ) (‪:Caller callBack‬‬
‫)(‪public Caller callBack‬‬
‫{‬
‫))(‪if(!this.postQueue().isEmpty‬‬
‫;))(‪return(this.postQueue().remove‬‬
‫‪else‬‬
‫;)‪return(null‬‬
‫}‬
‫ח‪ .‬נממש את הפעולה )(‪:addToPost‬‬
‫)‪public void addToPost(Caller c‬‬
‫{‬
‫;)‪this.postQueue().insert(c‬‬
‫;‪this.numCallers ++‬‬
‫}‬
‫הערה‪ :‬מי שבחרו שלא לייצג את התכונה של מספר ממתיני נוכחי בעמדה‪ ,‬לא יעדכנו את‬
‫התכונה במימוש זה‪.‬‬
‫ט‪ .‬ייצוג המחלקה ‪:Support‬‬
‫‪public class Support‬‬
‫{‬
‫מערך של עמדות ‪//‬‬
‫;‪private Post[] posts‬‬
‫שומר את מספר העמדה בה מינימום ממתינים ‪//‬‬
‫;‪private minPostIndex‬‬
‫‪10‬‬
‫}‬
‫הסבר‪ :‬המחלקה לניהול עמדות תמיכה מיוצגת ע"י מער חד&מימדי בגודל ‪ 20‬מטיפוס עמדה‬
‫)הפעולה הבונה תיצור זאת(‪ ,‬ובנוס" מספר העמדה בה מינימו ממתיני )הפעולה הבונה תציב‬
‫בתכונה זו ‪ 0‬כברירת מחדל(‪.‬‬
‫ג למי שייצגו את מספר הממתיני הנוכחי בכל עמדה אי שו חיוב ועקביות בקביעת‬
‫התכונה השומרת את מספר העמדה שבה אוס" ממתיני מינימלי בכל רגע‪ .‬החזקת תכונה‬
‫שכזו תחייב עדכוני במקומות שוני ואפשר בהחלט להחליט לוותר עליה ולבצע את החיפוש‬
‫של עמדה שכזו ברגע הנצר בלבד‪.‬‬
‫י‪.‬‬
‫נממש את הפעולה ‪) :positionCaller‬על פי הייצוג שלעיל(‬
‫)‪public void positionCaller(Caller c‬‬
‫{‬
‫;)‪this.posts[this.minPostIndex].addToPost(c‬‬
‫)‪for(int i=0; i<posts.length; i++‬‬
‫))(‪if(this.posts[i].lineLength()<this.posts[this.minPostIndex].lineLength‬‬
‫;‪this.minPostIndex = i‬‬
‫}‬
‫הסבר‪ :‬לאחר הוספת המתקשר לעמדה שבה אוסף מינימלי של ממתינים‪ ,‬יש לחזור‬
‫לבדוק ולעדכן את התכונה השומרת את מספרה הסידורי של העמדה שבה כרגע אוסף‬
‫מינימלי של ממתינים‪.‬‬
‫הערה‪ :‬מי שהחליטו שלא לייצג את ‪ Support‬בעזרת ‪ ,minPostIndex‬יצטרכו‬
‫להקדים את החיפוש אחר העמדה המינימלית לראשית מימוש הפעולה!‬
‫פתרו‪ #‬אפשרי לשאלה ‪3‬‬
‫ג‪ .‬נממש את הפעולה )‪ Node remove (Node p‬מתו ממשק הרשימה המעגלית‪:‬‬
‫)‪public Node remove(Node p‬‬
‫{‬
‫)‪if(this.first == p && p.getNext() == this.first‬‬
‫{‬
‫;‪this.first = null‬‬
‫;)‪return(null‬‬
‫}‬
‫‪else‬‬
‫{‬
‫)‪if(this.first==p‬‬
‫;)(‪this.first = p.getNext‬‬
‫;)(‪Node pos = p.getNext‬‬
‫)‪while(pos.getNext() != p‬‬
‫;)(‪pos = pos.getNext‬‬
‫;))(‪pos.setNext(p.getNext‬‬
‫;)‪p.setNext (null‬‬
‫;))(‪return (pos.getNext‬‬
‫}‬
‫}‬
‫ב‪.‬‬
‫‪11‬‬
public static List playGame(CircularList lst, int r)
{
Node p1 = null;
List tmp = new List();
Node p2 = lst.getFirst();
while(!lst.isEmpty())
{
for(int i=1; i<r; i++)
p2 = p2.getNext();
p1 = tmp.insert(p1,p2.getInfo());
p2 = lst.remove(p2);
}
return(tmp);
}
4 ‫ אפשרי שאלה‬#‫פתרו‬
:3 ‫ "פירמידה" בגובה‬-‫ צייר ע‬.‫ד‬
3
2
2
1
0
1
0
0
1
0
0
1
0
0
0
:‫ שתי אפשרויות‬.‫ב‬
:1 ‫אפשרות‬
public static Tree buildPyramidTree(int h)
{
if(h == 0)
return(new Tree(0));
return(new Tree(h, buildPyramidTree(h-1), buildPyramidTree(h-1)));
}
:2 ‫אפשרות‬
public static Tree buildPyramidTree(int h)
{
Tree t = new Tree(h);
if(h > 0)
{
t.setLeft(buildPyramidTree(h-1));
t.setRight(buildPyramidTree(h-1));
}
return(t);
}
12
:(null ‫ אינו‬tree&‫ פירמידה )בהנחה ש‬-‫ נתו הוא ע‬-‫ מימוש הפעולה הבודקת א ע‬.‫ג‬
public static boolean isPyramidTree(Tree tree, int h)
{
if(tree.getInfo() != h)
return(false);
if(h==0 && tree.isLeaf())
return(true);
if(tree.getLeft()==null || tree.getRight()==null)
return(false);
return(isPyramidTree(tree.getLeft(),h-1) && isPyramidTree(tree.getRight(),h-1));
}
5 ‫ אפשרי שאלה‬#‫פתרו‬
-‫ אינו ע‬2 -‫(; ע‬8 ‫ ולו ב ימני בעל ער‬9 ‫ בעל ער‬-‫ )קיי בו תת&ע‬,"‫ "מתכונת‬-‫ אינו ע‬1 -‫ ע‬.‫א‬
."‫ "מתכונת‬-‫ הוא ע‬3 -‫(; ע‬15 ‫ ולו ב שמאלי בעל ער‬16 ‫ בעל ער‬-‫ )קיי בו תת&ע‬,"‫"מתכונת‬
‫ לגבי הער‬.‫ הער הקט ביותר בו יימצא תמיד בשורש‬,"‫ ה"מתכונת‬-‫ בשל תכונותיו של ע‬.‫ב‬
‫ הסיבה לכ‬.‫ אול הוא בוודאות יימצא באחד מהעלי‬,‫הגדול ביותר אי&אפשר לדעת בדיוק‬
‫היא שלעלה אי א" ב לכ אי מספר גדול יותר ממנו ואילו האבא של העלה קט ממנו על פי‬
"‫ הער הגדול ביותר לא ימצא דווקא בעלה בעל ה"עומק‬:‫ )הערה‬.‫ מתכונת‬-‫ההגדרה של ע‬
(!-‫הגדול ביותר בע‬
:"‫ מתכונת‬-‫ בינרי הוא "ע‬-‫ פעולה חיצונית שבודקת הא ע‬.‫ג‬
public static boolean isMatkonetTree(Tree tree)
{
boolean left=true, right=true;
if(tree.getLeft() != null)
if(tree.getInfo() > tree.getLeft().getInfo())
return(false);
else
left = isMatkonetTree(tree.getLeft());
if(tree.getRight() != null)
if(tree.getInfo() > tree.getRight().getInfo())
return(false);
else
right = isMatkonetTree(tree.getRight());
return(left && right);
}
13
:‫ מתכונת‬-‫ בע‬x&‫ פעולה שמדפיסה את כל הערכי הקטני מ‬.‫ד‬
public static void printSmallsInMatkonet(Tree matkonet, int x)
{
if(matkonet.getInfo() < x)
{
IO.println(matkonet.getInfo());
if(matkonet.getLeft() != null)
printSmallsInMatkonet(matkonet.getLeft(),x);
if(matkonet.getRight() != null)
printSmallsInMatkonet(matkonet.getRight(),x);
}
}
‫ משו שהשאלה ביקשה‬,x =< ‫ יש לשי לב שבסעי" ד' האלגורית עוצר לאחר שנתקל בער‬:‫הערה‬
‫ אי חשיבות לסדר הדפסת הקדקודי‬.‫פתרו יעיל ככל האפשר – ויש להוריד נקודות למי שלא ביצע זאת‬
.‫בסעי" זה‬
6 ‫ אפשרי שאלה‬#‫פתרו‬
– ‫ מימוש פעולת ההכנסה לרשימה‬.‫א‬
public DoubleNode insert (DoubleNode pos, int info){
if (pos == null) {
//assume list is empty
this.head = new DoubleNode (info);
this.head.setNext (this.head);
this.head.setPrev (this.head);
return this.head;
}
else { // the list isn't empty
DoubleNode toInsert = new DoubleNode (info);
DoubleNode nextToPos = pos.getNext();
toInsert.setNext (nextToPos);
nextToPos.setPrev (toInsert);
pos.setNext (toInsert);
toInsert.setPrev (pos);
return toInsert;
}
}
14
:‫ מימוש פעולות ההוצאה מתור הממומש באמצעות רשימה מעגלית‬.‫ב‬
public int remove()
{
int ret = list.getFirst().getInfo();
list.remove (list.getFirst ());
return ret;
}
7 ‫ אפשרי שאלה‬#‫פתרו‬
:Flat ‫ייצוג המחלקה‬
.‫א‬
:‫להל מימוש הפעולות הבאות מתו ממשק הדירה‬
.‫ב‬
public class Flat {
private int flatNum;
private final int totalBeds;
private int occupiedBeds;
private String[] students;
}
public Flat(int flatNumber, int numBeds){
totalBeds = numBeds;
flatNum = flatNumber;
occupiedBeds = 0;
students = new String[totalBeds];
for (int i=0;i<students.length;i++) students[i]="";
}
public boolean addStudent(String name){
if (occupiedBeds==totalBeds) return false;
else {
for (int i=0; i<students.length;i++){
if (students[i].equals("")) {
students[i]=name;
occupiedBeds++;
return true;
15
}
}
return false; //to avoid compilation error
}
}
public boolean livesInFlat(String studentName){
for (int i=0; i<occupiedBeds; i++){
if (students[i].equals(studentName)) return true;
}
return false;
}
:Dorm ‫ייצוג המחלקה‬
.‫ג‬
:‫מימוש הפעולות מתו ממשק המחלקה‬
.‫ד‬
public class dorm{
Flat[][] flats;
}
public Dorm(){
flats = new Flat[9][30];
for (int i=0; i<flats.length;i++){
for (int j=0; j<flats[0].length;j++){
flats[i][j] = new Flat((100*(i+1))+j,i+1+(j%10));
//this solution implies that flats[0] = the 1st floor,
//not the 0th floor (which is public property
}
}
}
public int numEmptyBeds(int floor){
int sum = 0;
for (int i=0; i<flats[floor-1].length;i++){
sum+= flats[floor-1][i].getNumTotalBeds() –
flats[floor-1][i].getNumOccupiedBeds();
}
return sum;
16
‫}‬
‫פתרו‪ #‬אפשרי שאלה ‪8‬‬
‫א‪ .‬ע‪ 1 -‬אינו ע‪" -‬ברוש" – סכו תת&הע‪ -‬השמאלי של ‪ 14‬גדול מ&‪ ;14‬ע‪ 2 -‬הוא ע‪" -‬ברוש" – על‬
‫פי ההגדרה‪.‬‬
‫ב‪ .‬כ‪ .‬מכיוו שכל צומת גדול יותר מסכו כל הצמתי השמאליי‪ ,‬אי צור לעבור על תת הע‪-‬‬
‫השמאלי שלו‪ ,‬אלא רק לבדוק בתת&הע‪ -‬הימני‪ .‬למעשה‪ ,‬בפועל הצומת בו נמצא הער הגדול‬
‫ביותר יהיה תמיד הב "הכי רחוק" שאפשר להגיע אליו מהשורש על&ידי מעבר בכל פע לב‬
‫הימני בלבד‪ ,‬כלומר הער גדול ביותר בע‪" -‬ברוש" חייב להימצא רק על הענ" הימני ביותר‬
‫בע‪.-‬‬
‫ג‪ .‬פעולה חיצונית שבודקת הא ע‪ -‬בינרי הוא "ע‪ -‬ברוש"‪:‬‬
‫הערה‪ :‬הפעולה משתמשת בפעולת עזר בש )(‪ sumNodes‬שמקבלת ע‪ -‬ומחזירה את סכו ערכיו‪.‬‬
‫)‪public static boolean isBroshTree(Tree tree‬‬
‫{‬
‫;‪boolean left=true, right=true‬‬
‫)‪if(tree.getLeft() != null‬‬
‫))(‪if(tree.getInfo() < sumNodes(tree.getLeft‬‬
‫;)‪return(false‬‬
‫‪else‬‬
‫;))(‪left = isBroshTree(tree.getLeft‬‬
‫;)‪if(tree.getRight() != null‬‬
‫)))(‪if(tree.getInfo() > sumNodes(tree.getRight‬‬
‫;)‪return(false‬‬
‫‪else‬‬
‫;))(‪right = isBroshTree(tree.getRight‬‬
‫;)‪return(left && right‬‬
‫}‬
‫יש לממש את הפעולה )‪.... sumNodes(Tree t‬‬
‫‪17‬‬