1 / 27

תרגול 12:

תרגול 12:. Iterator מחסנית תור. מחסנית (stack). מחסנית ( stack ) היא מבנה נתונים שמזכיר מחסנית של רובה: האיבר שנכנס ראשון למחסנית יוצא ממנה אחרון ( LIFO - Last In First Out ). ניתן לראות במחסנית קופסה סגורה בעלת פתח יחיד, שדרכו נעשות פעולות הדחיפה והשליפה.

gwolf
Download Presentation

תרגול 12:

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: Iterator מחסנית תור

  2. מחסנית (stack) • מחסנית (stack) היא מבנה נתונים שמזכיר מחסנית של רובה: האיבר שנכנס ראשון למחסנית יוצא ממנה אחרון (LIFO - Last In First Out). • ניתן לראות במחסנית קופסה סגורה בעלת פתח יחיד, שדרכו נעשות פעולות הדחיפה והשליפה. • הטיפול דרך פתח יחיד יוצר מצב שבו איבר שנכנס אחרון יוצא ראשון- LIFO . • מחסנית היא שימושית כאשר יש צורך לשמור נתונים בסדר מסוים ולשלוף אותם בסדר הפוך.

  3. ממשק publicinterface Stack { /** *push-addsanelementtothestack. *@paramotheelementedtobeinsertedtothestack. */ publicvoid push (Object o); /** *pop-removesanelementformthestack(LIFOorder). *@returntheelementfromthetopofthestack. */ public Object pop (); /** *isEmpty-checksifthestackisemptyornot. *@returntrueifthereisnomoreelementsinthestack. */ publicboolean isEmpty(); }

  4. מימוש מחסנית בעלת ע"י מערך import java.util.EmptyStackException; publicclass StackAsArray implements Stack { /* Defines the initial capacity of a stack */ privatestaticfinalint INITIAL_CAPACITY = 5; /* Defines the capacity extension of a stack when it is full */ privatestaticfinalint CAPACITY_EXTENSION = 5; protected Object[] elements; protectedint size; /* Creates a new stack.*/ public StackAsArray() { elements = new Object[INITIAL_CAPACITY]; size = 0; }

  5. מימוש מחסנית ע"י מערך publicvoid push(Object o) { if (size >= elements.length) extend(); elements[size] = o; size = size + 1; } public Object pop() { if (size == 0) thrownewEmptyStackException(); size = size - 1; return elements[size]; } publicboolean isEmpty() { return size == 0; }

  6. מימוש מחסנית ע"י מערך privatevoid extend() { /* Create a new array with the new size */ Object[] tmpArray = new Object[elements.length + CAPACITY_EXTENSION]; /* Copy the old elements to the new array */ for (int i = 0; i < elements.length; i=i+1) tmpArray[i] = elements[i]; /* Replace the elements array with the new one */ elements = tmpArray; } }

  7. Iterator

  8. Iterator • מידע ונתונים (data) הדרושים לתכנית מחשב נשמרים בתוך מבנה נתונים (data structure). • על מבנה נתונים יש צורך לבצע מספר פעולות, כמו הכנסת נתונים והוצאת נתונים. • אחת הדרכים להוציא נתונים היא לעבור על אוסף הנתונים פריט-מידע אחר פריט-מידע. • האחריות על מבנה הנתונים היא של המתכנת שלו, ברצוננו להקל על המשתמש במבנה הנתונים ככל הניתן.

  9. Iterator • נרצה שתכונה זו תהיה משותפת למבני נתונים רבים, למשל לרשימה, שראינו זה עתה. • לכן נגדיר ממשק, שאותו כל מבנה נתונים יממש. • נרצה להגיד שמבנה נתונים הוא ניתן למעבר פריט-אחר-פריט, ובאנגלית: Iterable. ב-JAVA קיים הממשק: publicinterface Iterable { /** *Returnsaniteratoroverasetofelements. * *@returnanIterator. */ Iterator iterator(); }

  10. Iterator • יהיה לנו אובייקט שיעזור בתהליך. אובייקט זה יעבור על אוסף הנתונים פריט אחר פריט, לפי סדר מסוים, ובאנגלית:Iterator . ב-JAVA מוגדר ממשק לעבודה עם אובייקט כזה: publicinterface Iterator { boolean hasNext(); Object next(); void remove(); }

  11. publicinterface Iterator { /** *Returnstrueiftheiterationhasmoreelements. *@returntrueiftheiteratorhasmoreelements. */ boolean hasNext(); /** *Returnsthenextelementintheiteration. *@returnthenextelementintheiteration. * @exception NoSuchElementException iteration has no more elements. */ Object next(); /** *Removesfromtheunderlyingcollectionthelastelementreturnedbythe *iterator(optionaloperation) *@exceptionUnsupportedOperationExceptionifthe"remove" *operationisnotsupportedbythisIterator. * *@exceptionIllegalStateExceptionifthe"next"methodhasnot *yetbeencalled,orthe"remove"methodhasalready *beencalledafterthelastcalltothe"next" *method. */ void remove(); }

  12. שימוש ב-Iterator בהמשך נראה כיצד להפוך את המחלקה StackAsArrayכך שתתמוך ב-Iterator, כרגע נניח שהמחלקה כבר תומכת בו, ועל סמך זאת נעשה שימוש ב-Iterator שמתקבל מהשיטה iterator(), שמובטחת לנו מכיוון ש- StackAsArray מממשת את Iterable. publicstaticvoid main(String[] args) { StackAsArraystack= new StackAsArray(); stack.push("Tasty"); stack.push(“Are"); stack.push("Shnitsels"); Iterator it = stack.iterator(); while (it.hasNext()) { Object currentData = it.next(); System.out.print(currentData); if (it.hasNext()) System.out.print(", "); } System.out.println(); }

  13. מימוש ה-Iterator עבור StackAsArray publicclass StackAsArrayIterator implements Iterator { private int currentIndex; private Object[] Array; public ArrayIterator(int size, Object[] Array) { currentIndex = size; this.Array = Array; } publicboolean hasNext() { return (currentIndex != 0); } public Object next() { if (!hasNext()) { thrownew NoSuchElementException(); } currentIndex = currentIndex -1; Object data = arry[currentIndex]; return data; } publicvoid remove() { thrownewUnsupportedOperationException(); } }

  14. מימוש ה-Iterable במחלקה LinkedList עתה נראה כיצד נתמוך ב Iterator במחלקה LinkedList: publicinterface Iterable { /** *Returnsaniteratoroverasetofelements. * *@returnanIterator. */ Iterator iterator(); }

  15. מימוש ה-Iterable במחלקה StackAsArray • עכשיו כל מה שנותר לעשות הוא לממש את השיטה iterator() של הממשק Iterable ב StackAsArray: publicclass StackAsArray implements Iterable{ … protected Object[] elements; protectedint size; /* Creates a new stack.*/ public StackAsArray() { elements = new Object[INITIAL_CAPACITY]; size = 0; } … public Iterator iterator(){ returnnew StackAsArrayIterator(elements,size); } }

  16. הערות • Iterator מניח שלא נעשה שינוי באוסף עליו הוא עובר במהלך המעבר. אם נעשה שינוי – האיטרטור איננו במצב חוקי ואין הבטחה לפעולה תקינה שלו. • השיטה ()next מחוייבת לזרוק את החריגה NoSuchElementException במידה ואין יותר אלמנטים באוסף. ( אם לפני כל קריאה ל-next() נוודא ש hasNext() החזיר true אז לא נתקל בחריגה זו). • החריגה: UnsupportedOperationException נזרקת כאשר אנו מחוייבים להכריז שיטה מסויימת (למשל כי היא חלק מממשק) במחלקה שלנו, אך אנו לא תומכים בשיטה זו. לכן בגוף השיטה נזרוק את החריגה.

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

  18. המשך import java.util.Scanner; … publicstaticvoid main(String args[]) { Scanner sc = new Scanner(System.in); Queue s = new stackAsArray(); System.out.println("Insert few lines … "); while (sc.hasNextLine()) { String line = sc.nextLine(); s.push( line ); } System.out.println("Printing all the lines back! "); while (!s.isEmpty()) { System.out.println(s.pop()); } }

  19. לא תמיד נצטרך לדעת כיצד מימשו את הממשק– העתק מחסנית השיטה copy מקבלת כארגומנט מחסנית s ומחזירה העתק של המחסנית s כאשר יש לשמור על סדר האיברים במחסנית המועתקת וב-s זהה. publicstatic Stack copy(Stack s) { }

  20. לא תמיד נצטרך לדעת כיצד מימשו את הממשק– העתק מחסנית השיטה copy מקבלת כארגומנט מחסנית s ומחזירה העתק של המחסנית s כאשר יש לשמור על סדר האיברים במחסנית המועתקת וב-s זהה. publicstatic Stack copy(Stack s) { Stack temp = new StackImpl(); Stack ans = new StackImpl(); while (!s.isEmpty()) { temp.push(s.pop()); } while (!temp.isEmpty()) { Object o = temp.pop(); ans.push(o); s.push(o); } return ans; }

  21. תור - Queue •  תור (Queue) הוא מבנה נתונים המזכיר תור של בני אדם: האיבר שנכנס ראשון לתור- יוצא ממנו ראשון. • ניתן לראות כקופסה סגורה בעלת 2 פתחים: פתח הכנסה ופתח יציאה. • איבר שנכנס ראשון יוצא ראשון FIFO (FIFO - First In First Out). • שימושים: ניהל תהליכים ע"י מערכת ההפעלה, ניהול תור בבית מרקחת, ...

  22. public interface Queue{ /** *isEmpty-checksifthequeueisemptyornot. *@returntrueifthequeueisempty */ publicboolean isEmpty(); /** *dequeue-removesanobjectfromtheheadofthequeue. * (FIFOorder) *@returnthenextobjectinthequeue. */ public Object dequeue(); /** *enqueue-insertsanobjectintothequeue. *@paramotheobjecttobeenqueued. */ publicvoid enqueue(Object o); }

  23. דוגמה שיטה זו מקבלת תור כפרמטר והופכת את סדר האיברים בו. מוגדר לכם משתנה אחד מטיפוס.Object אין להגדיר משתנים נוספים בשיטה זו. publicstatic void reverse(Queue q) { Object o; }

  24. דוגמה שיטה זו מקבלת תור כפרמטר והופכת את סדר האיברים בו. מוגדר לכם משתנה אחד מטיפוס.Object אין להגדיר משתנים נוספים בשיטה זו. publicstatic void reverse(Queue q) { Object o; if(!q.isEmpty()){ o=q.deueue(); reverse(q); q.enqueue(o); } }

  25. תרגיל הוסיפו למחלקה StackAsArrayהמממשת את הממשק Iterable את השיטה filter לסינון איברים העונים על תנאי מתוך כלל איברי במחסנית. Stack filter(Filter f) התנאי ע"פ מסננים האיברים הוא Filter f. נגדיר ממשק Filter המכיל שיטה אחת והיא accept, המקבלת אובייקט ומחליטה האם הוא עובר את הסינון או לא.

  26. publicinterface Filter { /** *accept–definesthefiltrationcriterion. *@paramotheobjecttobeexamined. *@returntrueiftheobjectshould not be * filtered out. */ publicboolean accept(Object o); } אנו נממש Filter פשוט עבור המחלקה String, המשאיר רק את המחרוזות הלא ריקות: publicclass EmptyStringFilter implements Filter { publicboolean accept(Object o) { boolean ans = false; if (o instanceof String) { String s = (String) o; ans = s.length() > 0; } return ans; } }

  27. כל שנותר הוא לממש את השיטת הסינון ב- StackAsArray: השיטה מקבלת כקלט מסנן, ומחזיר מחסנית חדשה שתכיל את כל אברי המחסנית הנוכחית שעברו את המסנן. public stackAsArray filter(Filter filter) { stackAsArray filteredStack = new stackAsArray() ; Iterator it = this.iterator(); while (it.hasNext()) { Object data = it.next(); if(filter.accept(data)) { filteredStack.push(data) ; } } return filteredStack; }

More Related