תרגיל 6 בקורס תוכנה 1 סמסטר ב' תשס"ח

 

חלק 1: הורשה

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

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

Expressionישות המייצגת ביטוי כלשהו.

Literalישות המתארת מספר בודד (double).

BinaryOpישות המתארת פעולה בינארית (פעולה על שני ביטויים).

TrenaryOpישות המתארת פעולה טרינארית (פעולה על שלושה ביטויים).

Sumישות המתארת סכום.

Product - ישות המתארת מכפלה.

Exponent - ישות המתארת חזקה.

CondExpישות המתארת פעולה על שלושה פרמטרים a, b, c שהיא a ? b : c  . שערוך הביטוי מתבצע כך: אם ערכו של a שונה מ 0.0 יוחזר ערכו של b אחרת יוחזר ערכו של c.


בדקו את עצמכם ע"י קוד הלקוח הבא:

public class Client {

     public static void main(String[] args) {

           Expression l1 = new Literal(1.0);

           Expression l2 = new Literal(2.0);

           Expression l3 = new Literal(3.0);

           Expression sum = new Sum(l1, l2);

           Expression e1 = new Exponent(l3, sum);

          

           Expression prod = new Product(l1, l2);

           Expression exp = new Exponent(l2, l3);

           Expression e2= new CondExp(sum, prod, exp);

          

           System.out.println(e1 + " = " + e1.eval());                         

System.out.println(e2 + " = " + e2.eval());    

     }

}

פלט התוכנית הוא:

(3.0) ^ ((1.0) + (2.0)) = 27.0

((1.0) + (2.0)) ? ((1.0) * (2.0)) : ((2.0) ^ (3.0)) = 2.0


הערות:

  public double  eval()

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



חלק שני: אוספים ממוינים

קובצי עזר להורדה

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

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

חשוב לשים לב כי כל ה-Sets שנתעסק איתם הינם בלתי ניתנים לשינוי, ז"א שהעצמים בתוכם נקבעים בעת היצירה. לא ניתן להוסיף/להוריד עצמים לאחר מכן מן האוספים. תכונה זו תאפשר לכם לשמור תוצאות של חישובים ארוכים יחסית (ערך מקס', ערך מינ', גודל) ולא לחשב אותם כל פעם מחדש.

 

שימו לב לאיטרטור SortedIterator, הרחבה ריקה של Iterator שמסמלת כי האיטרטור מחזיר ערכים ממוינים.

 

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

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

size()

-->isEmpty()

-->getMinumum()

-->getMaximum() 

ב. המחלקה MergedSortedSet שנבנית באמצעות SortedSet A ו-SortedSet B מכילה רק עצמים בחיתוך של A ו-B (ז"א עצמים הנמצאים בשניהם). עבור מחלקה זו עליכם לממש:

בנאי

-->contains()

-->iterator()

יצירת איטרטור צריכה להראות כך:

/**      

 * Returns an Iterator for the elements of this set.

*/

public SortedIterator iterator() {

          return new MergedSortedIterator(setA.iterator(), setB.iterator());

}

 

כמובן שתצטרכו לממש גם את MergedSortedIterator המרחיב את SortedIterator 

ג. המחלקה DifferenceSortedSet שנבנית באמצעות SortedSet A ו-SortedSet B מכילה רק עצמים שנמצאים ב-A אך לא נמצאים ב-B. ממשו מחלקה זו (ואת האיטרטור המתאים לה) כמחלקה מרחיבה ל-CompositeSortedSet. 

            ד. המחלקה UnifiedSortedSet מכילה את כל העצמים מ-A ומ-B. ממשו אותה בדומה לסעיפים הקודמים.