1 / 29

לקראת בגרות תרגילים ברשימות ועצים

לקראת בגרות תרגילים ברשימות ועצים. עיצוב תוכנה : השתלמות ת"א 12/3/2009 – רחל לודמר, זיוה קוצמן, דיתה אוהב ציון. טיפים לשאלות לקראת בגרות. הערות והארות שנאמרו / הועלו במפגש ההשתלמות.

lucius
Download Presentation

לקראת בגרות תרגילים ברשימות ועצים

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. לקראת בגרות תרגילים ברשימות ועצים עיצוב תוכנה : השתלמות ת"א 12/3/2009 – רחל לודמר, זיוה קוצמן, דיתה אוהב ציון

  2. טיפים לשאלות לקראת בגרות הערות והארות שנאמרו / הועלו במפגש ההשתלמות • לכל פעולה יש להוסיף תיעוד: טענת כניסה ויציאה. בבגרות אם אין תיעוד לשאלה מורידים 5% מהשאלה (2 נקודות).במצגת זו לא נרשמו טענות כניסה ויציאה מטעמי חיסכון באורך הטקסט בשיקופית. • איתחול והצהרה של משתנים מקומיים בכל פעולה. • תרגול של כתיבת פעולות פנימיות. (ראה בחינות בגרות במתכונת החדשה) • בבעיות מורכבות מומלץ שיהיו לפחות 2 מחלקות ולא יותר מ-4. • בבעיות מורכבות, אין צורך במימוש פעולות האיחזור והקביעה.((get, setיש צורך ברישום ההנחה שהפעולות קיימות ואין צורך לממשם. • שימוש תחבירי נכון של פעולות ה- set, get עבור תכונות כאשר נמצאים מחוץ למחלקה שבה הוגדרו : ()התכונה.get.שם העצם (פרמטר)התכונה.set.שם העצם יש להקפיד על אות גדולה במקום הנכון (בתכונה) בהתאם לכללי השפה. • כשיש "הרכבה" של איחזור תכונות במבנה מורכב, רצוי להשתמש במשתני עזר ב"דרך", על מנת למנוע בלבול וסרבול. • זהירות מירבית בתרגום של שאלות במתכונות הישנה והתאמתן למתכונות החדשה, כדוגמת שאלות בעצים המוגדרות על עץ ריק. כלל: אם אתה המורה מתלבט ב"ניסוח החדש" לשאלה, אל תבקש מהתלמיד ל"פתור את התלבטויותיך"- וותר על שאלה זו.

  3. תרגיל 1:כתוב פעולה חיצונית המקבלת רשימה של מספרים שלמים, ומספר נוסף x.על הפעולה להחזיר את המספר הקרוב ביותר ל- x, אשר גדול או שווה לו.אין להשתמש במבנה נתונים כלשהו נוסף, גם לא ברשימת עזר. אם אין איבר ברשימה הגדול מ- xיש להחזיר 999-דוגמא: עבור הרשימה lst: 7, 4, 12, 6,10,15 והמספר x=8 יוחזר 10. פתרון: יש לחפש את ההפרש הקטן ביותר מבין כל ההפרשים של: num - x}} כאשר num>x public static int nearX(list<Integer> lst) } Node<Integer> pos=lst.getFirst(); while (pos!=null && pos.getInfo()<x) pos=pos.getNext();if (pos==null) return -999; int min=pos.getinfo()-x; while(pos!=null) { if (pos.getInfo()-x<min && pos.getinfo()>= x) min=pos.getInfo()-x; pos=pos.getNext();} return min+x; }

  4. תרגיל 2: נתונה הפעולה הבאה: lastAndRemove אשר מקבלת רשימת מספרים לא ריקה, הפעולה מוחקת את האיבר האחרון ברשימה ומחזירה את ערכו. א. ממש פעולה זו: public static int lastAndRemove(List<Integer> lst) נתון ה- UML הבא: הנח שנבנתה מחלקה מתאימה עבור UML זה הכולל : תכונות , פעולה בונה, פעולות איחזור וקביעה. ב. כתוב פעולה חיצונית המקבלת רשימת מספרים שלמים lst1, ומחזירה רשימת מספרים חדשה lst2 שכל איבר שלה הוא זוג מספרים הנמצאים במרחק שווה מקצות הרשימה. כלומר האיבר הראשון ברשימה lst2 יהיה הזוג המורכב מהראשון והאחרון מרשימה lst1, האיבר השני ב- lst2 יהיה הזוג המורכב מהשני והלפני האחרון ברשימה lst1, וכך הלאה. אם הרשימה היא באורך אי זוגי האיבר האמצעי ישוכפל. למשל, עבור הרשימה: lst1 475326null הרשימה שתוחזר:

  5. public static int lastAndRemove(List<Integer> lst) { Node<Integer>pos=lst.getFirst(); while (pos.getNext()!=null) pos=pos.getNext(); int last=pos.getInfo(); lst.remove(pos); return last; } פתרון א:

  6. פתרון ב: public static List<TwoItems> zugot(List<Integer> lst1) { List<TwoItems>lst2=new List<TwoItems> (); Node<TwoItems> p=lst2.getFirst(); while(!lst1.isEmpty()) { int x=lst1.getFirst().getInfo(); int y=lastAndRemove(lst1); TwoItems t=new TwoItems(x,y); p=lst2.insert(p,t); if (!lst1.isEmpty()) lst1.remove(lst1.getFirst()); //מחיקת האיבר הראשון ברשימה } return lst2; }

  7. שאלה 3: "עץ עוקבים - n" הוא עץ המכיל את כל המספרים השלמים מ- 1 עד n , כשכל מספר מופיע בו פעם אחת בלבד. כתוב פעולה המקבלת עץ t ומספר טבעי n, ומחזירה אמת אם העץ הוא "עץ עוקבים - n", ושקר אחרת. (האם בהכרח מספר הצמתים הוא n?) public static boolean okvimN(BinTreeNode<Integer> bt, int n) { for (int x=1; x<=n; x++) if (countItem(bt,x)!=1) return false; return true; } הפעולה נעזרת בפעולת עזר המונה כמה פעמים הופיע ערכו של צומת אפשר לפתור את הבעיה גם בעזרת מערך מוניםביעילות טובה יותר. public static int countItem(BinTreeNode<Integer> bt, int x) { if (bt==null ) return 0; else if (bt.getInfo()==x) return (1+countItem(bt.getLeft(),x)+countItem(bt.getRight(),x)); else return (countItem(bt.getLeft(),x)+countItem(bt.getRight(),x)); }

  8. 4 3 6 7 1 5 2 שאלה 4: נגדיר רשימה-ציקלית כרשימה שבה בכל חוליה, שדה המידע מכיל מספר סידורי של חוליה אחרת ברשימה. כך שאם נתחיל בחוליה הראשונה ונעבור ממנה לחוליה הבאה (בהתאם לתוכן שלה) וכך הלאה בהתאם לתכני החוליות – נגיע בסוף חזרה לחוליה הראשונה , אחרי שעברנו על כל החוליות. הנח שערכי האיברים ברשימה הציקלית הם שונים זה מזה. לדוגמא : עבור הרשימה הבאה: 7 6 5 4 3 2 1 המסלול יהיה (משמאל לימין): 1→ 4 → 7 → 2 → 3→ 6 → 5 → 1 לפניך מספר פעולות : א. ממש את הפעולה Node<Integer> getPosition(List<Integer> L , int n) ב. ממש את הפעולה boolean isCyclic(List<Integer> L) . ניתן להשתמש בפעולה lenList(List <Integer> L) , מבלי לממש אותה.

  9. 7 6 5 4 3 2 1 4 3 6 7 8 5 2 פתרון – רשימה צקלית public static Node<Integer> getPosition(List<Integer> L , int n) { Node<Integer> pos=L.getFirst(); for (int i=1; i<n && pos!=null; i++) pos=pos.getNext(); return pos; } public static boolean isCyclic(List<Integer> L) { int n=lenList(L); Node<Integer> pos=L.getFirst(); List<Integer> L2=new List<Integer>(); Node<Integer> pos2=L2.getFirst(); pos2=L2.insert(pos2,1); int mone=1; while(pos!=null && pos.getInfo()!=1 && mone<n) { pos2=L2.insert(pos2,pos.getInfo()); pos=getPosition(L , pos.getInfo()); mone++; } if (mone==n && pos!=null) return true; else return false; } בנית הרשימה החדשה אינה חובה. אפשר להשתמש במונה. שים לב,לתנאי הנוסף!למרות שעברנו על כל החוליות, לא הגענו בחזרה לחוליה הראשונה.

  10. שאלה 5: • בסופר-מרקט יש k שורות המכילות עגלות (השורות באורכים שונים). אדם המבקש לקחת עגלה, בוחר בעגלה האחרונה משורה כלשהי. אדם שמחזיר עגלה מחבר אותה לעגלה האחרונה בשורה כלשהי (השורה יכולה להיות שונה מזו שנלקחה).כל עגלה מזוהה ע"י קוד משלה ((code ומספר המציין כמה פעמים נלקחה העגלה (count). • א. כתוב את הכותרת ואת התכונות בעבור כל אחת מהמחלקות: • עגלה - Carriage • שורת עגלות - LineCarriage • מאגר עגלות בסופר - SuperCarriage • ב. כתוב פעולה פנימית בשם takeCarriage (במחלקה(LineCarriage . • הפעולה מחזירה את העגלה שהאדם לקח מהשורה. • ג. כתוב (במחלקה LineCarriage) פעולה פנימית בשם returnCarriage המקבלת כפרמטר עגלה a ומחזירה אותה לשורה. • ד. כתוב פעולה פנימית במחלקה superCarrige המחזירה את המיקום (הפניה) לעגלה הפופולארית. עגלה פופולארית היא זו שנלקחה מספר פעמים רב ביותר.הנח שיש אחת כזו. • הערה : הנח כי במחלקות שלעיל קיימות כל הפעולות המאחזרות get והפעולות הקובעות set.

  11. public class Carriage { private int code; private int count; ........... } א. הגדרת המחלקות: אפשר גם מחסנית פחות נוח לעבודהבסעיפים ד-ה public class LineCarriage { private List<Carriage> line; ........... } מותר לקחת ולהחזיר עגלה רק בסוף השורה public class SuperCarriage { private LineCarriage [ ] allLines;................ }

  12. ב. פעולה פנימית במחלקה LineCarriage ללקיחת עגלה public Node<Carriage> getLast() { Node<Carriage>pos= this.line.getFirst(); while (pos.getNext()!=null) pos=pos.getNext(); return pos; } ניעזר בפעולת עזר המחזירה (הפניה) לעגלה האחרונה public Carriage takeCarriage() { Node<Carriage>pos= this.line.getLast(); Carriage a=pos.getInfo(); a.setCount(a.getCount()+1); this.line.remove(pos); return a; } ג. פעולה פנימית במחלקה LineCarriage להחזרת עגלה public void returnCarriage( Carriage a) { Node<Carriage>pos= this.line.getLast(); this.line.insert(pos,a); }

  13. ד. פעולה פנימית במחלקה superCarriage להחזרת ההפניה לעגלה הפופולרית public Node<Carriage> popularCarriage() { int max=0; Node<Carriage> popular=null; for (int i=0; i<this.allLines.length; i++) { Node<Carriage> pos=this.allLines[i].getLine().getFirst(); while (pos!=null) { if (pos.getInfo().getCount()>max) { max= pos.getInfo().getCount(); popular=pos; } pos=pos.getNext(); }//end while } //end for return popular; }

  14. תוספת ** (לתרגול בכיתה) הסופר קבל עגלות חדשות (מספרן קטן מאד ביחס למספר העגלות הכללי), ומעוניין להחליף את העגלות הפופולאריות ביותר, בסדר יורד.כתוב פעולה פנימית במחלקה superCarrige המקבלת רשימה של קודים של עגלות חדשות, ומחליפה את העגלות הפופולאריות (בסדר יורד) בעגלות חדשות.היעזר בפעולה שבסעיף ד', ובאם נעזרת בפעולות נוספות יש לממש אותן ולציין באיזו מחלקה נכתבו. public void replaceCarriage(List<Integer> codeL) { Node<Integer> p=codeL.getFirst(); while (p!=null) { Node<Carriage> pos=this.allLines.popularCarriage(); Carriage a=pos.getInfo(); a.setCode(p.getInfo()); a.setCount(0); pos.setInfo(a); p=p.getNext(); } {

  15. שאלה 6:נתונה הפעולה הבאה: public static boolean sodTree(BinTreeNode<Integer> t) { If (Leaf(t)) return true; if (t.getLeft()!=null) if (Leaf(t.getLeft()) && t.getRight()!=null) return sodTree(t.getRight()); return false; } א. תן דוגמא לעץ בינארי המכיל לפחות 5 צמתים, כך שהפעולה sodTree תחזיר 'אמת'. ב. תן דוגמא לעץ בינארי המכיל לפחות 5 צמתים, כך שהפעולה sodTree תחזיר 'שקר'. ג. מה מטרת הפעולה sodTree? פעולת "עץ עלה" - Leaf, נתונה! א. ב. ג. המטרה היא להחזיר אמת אם העץ הוא עץ שורש או עץ עם שני תתי עצים כך שכל תת עץ שמאלי הוא עלה וכל תת עץ ימני מקיים את מטרת העץ.

  16. C 3 D 2 E 3 B 2 C 1 T 2 C 2 E 1 שאלה 7: נתון ה- UML הבא: הנח שנבנתה מחלקה מתאימה עבור UML זה הכולל : תכונות , פעולה בונה, פעולות איחזור וקביעה. כתוב פעולה חיצונית המקבלת עץ בינארי שאיבריו הם מטיפוס Pair. על הפעולה להחזיר רשימה שאיבריה הם התווים שבערכי הצמתים, תווים זהים יהיו ברצף, ואורך הרצף יהיה סה"כ מספר הופעות התו בעץ. אין חשיבות לסדר רצפי התווים ברשימה.לדוגמא, עבור העץ הבא: הרשימה שתוחזר:

  17. פתרון: שים לב בנוסף לעץ , הפעולה מקבלת גם רשימה מאותחלת. public static void ex7(BinTreeNode<Pair> bt, List<Character>lst) { if (bt!=null) { putInList(lst,bt.getInfo().getTav(),bt.getInfo().getNum()); ex7(bt.getLeft(),lst); ex7(bt.getRight(),lst); } } מימוש פעולת העזר: public static void putInList(List<Character>lst, char tav, int count) { Node<Character> pos = lst.getFirst(); while (pos!=null && pos.getInfo()!=tav) pos=pos.getNext(); for (int i=1; i<=count; i++) lst.insert(pos,tav); }

  18. שאלה 8: נתון ה- UML הבא: הנח שנבנתה מחלקה מתאימה עבור UML זה הכולל : תכונות , פעולה בונה, פעולות איחזור וקביעה. נתונה רשימת מספרים שאבריה הם מטיפוס Pair. התכונה value מייצגת ערך האיבר ברשימה, והתכונה howManyBig מייצגת את מספר האיברים ברשימה שאחרי האיבר הנוכחי, כך שערך התכונה value שלהם גדולה מערך התכונה value של האיבר הנוכחי. לדוגמא: כתוב פעולה חיצונית בשם addNumber המקבלת כפרמטרים רשימה L שאיבריה מטיפוס Pair, מספר שלם num ומספר שלם place. על הפעולה להוסיף איבר לרשימה L , כך שערך תכונת ה- value שלו הוא num, במקום סידורי place ברשימה, (ה-place של האיבר הראשון ברשימה הוא 1).יש לעדכן את הרשימה L, כך שאחרי ההכנסה יש לשמור על חוקי הרשימה לגבי התכונה howmanyBig. לדוגמא: עבור הרשימה הנ"ל והזימון addNumber(L,3,5) , הרשימה תעודכן ל-

  19. public static void addNumber(List<Pair> lst, int num, int place ) { Node<Pair> pos=lst.getFirst(), pos2; Pair x=new Pair(num,0); If (place==1) lst.insert(null,x); else { for (int i=1; i<place; i++) pos=pos.getNext(); lst.insert(pos,x); } pos=lst.getFirst(); for (int i=1; i<place; i++) { if( pos.getInfo().getValue()<num) { int t= pos.getInfo().setHowManyBig(); pos.getInfo().setHowManyBig(t+1);} pos=pos.getNext(); } int count=0; pos2=pos.getNext(); while(pos2!=null) { if (pos2.getInfo().getValue()>num) count++; pos2=pos2.getNext(); } pos.getInfo().setHowManyBig(count); } פתרון: הנחה: place תקין בתחום גודל הרשימה. • עדכון הרשימה:את הרשימה ניתן לעדכן עי" לולאה כפולההעוברת על כל איבר, וסופרת מחדש כמה גדולים ממנו והלאה – יעילות o(n2). • הפתרון המוצג הוא ביעילות o(n): • עדכון כל איבר הקטן מ – num ונמצא לפניו. (פעולה שניתן לבצעה תוך כדי איתור מיקומו הסידורי של num) • עדכון החוליה של num במספר האיברים שגדולים ממנו ונמצאים אחריו.

  20. 8 8 16 16 11 11 20 15 14 14 12 12 25 25 13 28 10 16 19 19 שאלה 9: נתונה השיטה הבאה, המקבלת שורש של עץ בינרי ומספר שלם. public static boolean sod(BinTreeNode<Integer> t, int num) { if(t==null) return true; return (t.getInfo() > num && sod(t.getLeft(), t.getInfo()) && sod(t.getRight(), t.getInfo())); } עבור העץ הבינרי הבא : א. מה תחזיר הפעולה עבור הזימון:sod(t,-1) ? ב. שנה ערכו של צומת אחת או יותר, כך שהפעולה תחזיר ערך שונה מזה שקבלת בסעיף א'. על השינוי להיות מינמלי בעץ. צייר מחדש את העץ המעודכן. א. מטרת הפעולה להחזיר אמת אם ערך שורש העץ גדול מ- num נתון, וערך של כל בן גדול מערך אביו. ב.

  21. a c b e d f שאלה 10: נתונה הפעולה Mystery הבאה שמקבלת כפרמטר הפניה לשורש של עץ בינרי: public static void Mystery(BinTreeNode<char> t) { if (t != null) { Console.WritLine (t.GetInfo() + " "); Mystery (t.GetLeft()); Console.WritLine (t.GetInfo()+ " "); Mystery (t.GetRight()); Console.WritLine (t.GetInfo()+ " "); } } (i)מה תדפיס הפעולה mystery כאשר היא תקבל את השורש של העץ root הבא? root ii)) ציירו עץ שאם root פונה לשורש שלו אז קריאה ל- mystery(root) תדפיס את השורה הבאה:b a c c d d d c a e e f f f e a b b

  22. b c a d e f פתרון: א. a,b,b,d,d,d,b,a,c,e,f,f,f,e,e,c,c,a ב. עבור הפלט: b a c c d d d c a e e f f f e a b b העץ שיתקבל: שאלה 11: רשימה מחזורית היא רשימה המורכבת רק מסדרה החוזרת על עצמה מספר שלם של פעמים, אך לא פחות מפעמיים. (הנתונים בסדרה אינם חוזרים על עצמם). דוגמה: 5,8,3, 5,8,3, 5,8,3 כתוב פעולה חיצונית, המקבלת רשימה L של מספרים שלמים ומחזירה 'אמת' אם הרשימה היא מחזורית ו'שקר' אחרת

  23. public static bool Machzorit(List<int> l) { bool takin = true; int count=1, mone=0; Node<int> pos1 = l.GetFirst(), pos2 = null; if (pos1 != null) pos2 = pos1.GetNext(); while (pos2 != null && pos2.GetInfo() != pos1.GetInfo()) { pos2 = pos2.GetNext(); count++; } if (pos2 == null) return false; while (pos2 != null && takin ) { if (pos1.GetInfo() == pos2.GetInfo()) { mone++; pos1 = pos1.GetNext(); pos2 = pos2.GetNext(); } else takin = false; if (mone==count) mone=0; } return (pos2 == null && takin && mone==0) }

  24. שאלה 12: תאומים הם שני אחים בעץ שערכם שווה. עץ תאומים הוא עץ עלה או שורש ושני תתי עצים, שכל אחד מהם הוא עץ תאומים, כך שמספר התאומים בתת העץ השמאלי קטן או שווה למספר התאומים בתת העץ הימני. כתבו פעולה המקבלת עץ בינארי ומחזירה 'אמת' אם הוא עץ תאומים ו'שקר' אחרת. דוגמא לעץ שאינו עץ תאומים דוגמא לעץ תאומים פתרון: נפרק את הבעיה לשתי תתי משימות : - בדיקה שכל 2 אחים הם תאומים - מספר התאומים בכל תת עץ שמאלי קטן או שווה למספר התאומים בתת עץ ימני

  25. public static boolean leaf(BinTreeNode<Character> bt) { return ( bt.getLeft()==null && bt.getRight()==null); } פתרון: public static int countTwins(BinTreeNode<Character> bt) } if (leaf(bt)) return 1; else return (1+countTwins(bt.getLeft())+ countTwins(bt.getRight())); { public static boolean twins(BinTreeNode<Character> t) { if (leaf(t)) return true; if( t.getLeft()!=null && t.getRight()!=null) { if (t.getLeft().getInfo()==t.getRight().getInfo()) { boolean ok= twins(t.getLeft()) && twins(t.getRight()); return ok && } else return false; } return false; } return false; } countTwins(t.getLeft())-1<=countTwins(t.getRight())-1; לא חובה להוריד 1 מכל מניית התאומים בתת עץ. וזאת על מנת שלא ימנה את שורש התת עץ במספר התאומים.

  26. 54 9 2 21 9 2 21 54 שאלה 13: • נתונה רשימה של מספרים שלמים באורך n (n זוגי). • קיימת מחלקה בשם TwoLists ובה שתי תכונות: • List<int> listA • List<int> listB • עליכם לממש את הפעולה החיצונית הבאה: • public static TwoLists Split(List<int> lst) • על הפעולה לחלק את איברי הרשימה הנתונה לשתי רשימות, כל אחת באורך n/2 , כך שההפרש בין סכום איברי שתי הרשימות יהיה המכסימלי. הפעולה צריכה להחזיר אובייקט מהמחלקה TwoLists המכיל את שתי הרשימות החדשות. • לדוגמה: אם הרשימה עליה מופעלת הפעולה היא: אז האובייקט שיוחזר יהיה : דרך פתרון: לבנות שתי רשימות מטיפוס TwoLists האחת תכיל את המספרים המכסימליים והשניה תכיל את המינימליים. כל אחת באורך .n/2

  27. public static Node<int> MaxInList(List<int> l) { Node<int> pos = l.GetFirst(); int max = pos.GetInfo(); Node<int> placeMax = pos; pos = pos.GetNext(); while (pos != null) { if (pos.GetInfo() > max) { max = pos.GetInfo(); placeMax = pos; } pos = pos.GetNext(); } return placeMax;} פתרון: הפעולה מחזירה הפניה לאיבר המכסימלי ברשימה l public static Node<int> MinInList(List<int> l) { Node<int> pos = l.GetFirst(); int min = pos.GetInfo(); Node<int> placeMin = pos; pos = pos.GetNext(); while (pos != null) { if (pos.GetInfo() < min) { min = pos.GetInfo(); placeMin = pos; } pos = pos.GetNext(); } return placeMin;} הפעולה מחזירה הפניה לאיבר המינימלי ברשימה l

  28. בניית צמד הרשימות: public static TwoLists Split( List<int> lst) { TwoLists t = new TwoLists(); List<int> la = t.GetA(); List<int> lb = t.GetB(); Node<int> p = lst.GetFirst(), placeMin, placeMax; while (!lst.IsEmpty()) { placeMin = MinInList(lst); placeMax = MaxInList(lst); la.Insert(null, placeMIn.GetInfo()); lb.Insert(null, placeMax.GetInfo()); lst.Remove(placeMax); lst.Remove(placeMIn); } return t; } הערה: שימוש בפעולת עזר אחת!אפשר לפתור בדרך אחרת: למצוא n/2 פעמים את הערכים המינימליים ולהעבירם לרשימה la , את n/2 הנותרים יש להעביר/ להעתיק לרשימת המכסימליים lb

  29. תודה רבה!

More Related