חומרי לימוד - מדעי המחשב

Transcription

חומרי לימוד - מדעי המחשב
‫א'‪/‬אדר‪/‬תשע"ה‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫‪ L‬היא רשימה המכילה מספרים שלמים שונים זה מזה וממוינים בסדר עולה‪ .‬רשימת הטווחים של ‪ L‬היא רשימה‬
‫חדשה שנבנית באופן הזה‪ :‬בעבור כל רצף של מספרים עוקבים ב‪ L-‬יהיה ברשימת הטווחים איבר אחד שמכיל‬
‫שני מספרים‪ .‬מספר אחד הוא המספר הקטן ביותר ברצף‪ ,‬והמספר השני הוא המספר הגדול ביותר ברצף‪.‬‬
‫רצף יכול להיות באורך ‪ 1‬או יותר‪ .‬אם הרצף הוא באורך ‪,1‬‬
‫לפניך תיאור חלקי של המחלקה ‪RangeNode‬‬
‫הוא מיוצג ברשימת הטווחים ע"י איבר ששני המספרים בו שווים‪.‬‬
‫המייצגת איבר ברשימת הטווחים‪.‬‬
‫‪RangeNode‬‬
‫המספר הקטן ביותר ברצף‬
‫;‪private int from‬‬
‫המספר הגדול ביותר ברצף‬
‫;‪private int to‬‬
‫)‪public RangeNode(int from, int to‬‬
‫א‪-‬‬
‫ממש ב‪ c#-‬פעולה חיצונית שתקבל רשימה לא ריקה‪ ,‬המכילה מספרים שלמים שונים זה מזה וממוינים‬
‫בסדר עולה‪ ,‬ותחזיר את רשימת הטווחים שלה‪.‬‬
‫כותרת הפעולה היא‪public static List<RangeNode> CreateRangeList(List<int> sourceList) -‬‬
‫ב‪-‬‬
‫מהי סיבוכיות זמן הריצה של הפעולה ‪ ?CreateRangeList‬נמק‪.‬‬
‫‪‬‬
‫הנח שלכל אחת מהתכונות במחלקה ‪ RangeNode‬יש פעולות ‪ Get‬ו‪ .Set-‬אתה יכול להשתמש בפעולות אלה‬
‫ובפעולה הבונה של המחלקה ‪ RangeNode‬בלי לממשן‪ .‬אם אתה משתמש בפעולות נוספות עליך לממשן‪.‬‬
‫‪‬‬
‫ניתן להשתמש בפעולות הממשק של חוליה ושל רשימת חוליות ואין צורך לממש אותן‪.‬‬
‫‪‬‬
‫הנח כי כל פעולות הממשק הבסיסיות של חוליה ושל רשימת חוליות (למעט ‪ )ToString‬הן בסיבוכיות זמן ריצה של‪.O(1) -‬‬
‫‪1‬‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫פתרון – פעולת עזר עבור רצף בודד – דרך א' ‪ -‬מחזירה ‪int‬‬
‫} )‪public static int LastInSequenceList(Node<int> p‬‬
‫‪//‬מחזירה את המספר האחרון ברצף‪ ,‬שהוא המספר הגדול ביותר ברצף המספרים העוקבים החל מהחוליה המתקבלת‪.‬‬
‫תזכורת ‪ -‬החוליה שמשתנה כאן‪ ,‬משתנה גם בפעולה העיקרית‬
‫‪//‬הנחה ‪ -‬החוליה היא מקום תקין ברשימה שאותחלה ומכילה מספרים שלמים שונים זה מזה וממוינים בסדר עולה‬
‫;‪bool flag = true; int x_prev‬‬
‫{ )‪if (p != null‬‬
‫;)(‪x_prev = p.GetInfo(); p = p.GetNext‬‬
‫‪//‬רצים על הרצף ‪ -‬עד שמגיעים לערך שלא עונה לרצף ‪ -‬לא עוקב ‪ -‬או לסוף הרשימה‬
‫{ )‪while (p != null && flag‬‬
‫{ )‪if (p.GetInfo() == x_prev + 1‬‬
‫;)(‪x_prev = p.GetInfo‬‬
‫} ;)(‪p = p.GetNext‬‬
‫‪else‬‬
‫};‪flag = false‬‬
‫‪//‬האחרון ברצף הוא הגדול ביותר ‪ -‬כיוון שהרשימה ממוינת‬
‫} ;‪return x_prev‬‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫‪2‬‬
‫‪1‬‬
‫א'‪/‬אדר‪/‬תשע"ה‬
‫פתרון – הפעולה העיקרית מחזירה רשימת טווחים ‪ -‬דרך א'‬
‫)‪public static List<RangeNode> CreateRangeList(List<int> sourceList‬‬
‫{‬
‫‪//‬מחזירה את רשימת הטווחים של הרשימה המתקבלת‬
‫‪//‬הנחה ‪ -‬הרשימה אותחלה ומכילה מספרים שלמים שונים זה מזה וממוינים בסדר עולה‬
‫;)(>‪List<RangeNode> l_new = new List<RangeNode‬‬
‫;)(‪Node<RangeNode> p_new = l_new.GetFirst‬‬
‫;‪int x_min, x_max‬‬
‫;)(‪Node<int> p = sourceList.GetFirst‬‬
‫)‪while (p != null‬‬
‫{‬
‫;)(‪x_min = p.GetInfo‬‬
‫;)‪x_max = LastInSequenceList(p‬‬
‫;))‪p_new = l_new.Insert(p_new, new RangeNode(x_min, x_max‬‬
‫}‬
‫} ;‪return l_new‬‬
‫‪3‬‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫פתרון – פעולת עזר עבור רצף בודד – דרך ב' ‪ -‬מחזירה‬
‫‪RangeNode‬‬
‫} )‪public static RangeNode SequenceToRangeNodeList(Node<int> p‬‬
‫‪ //‬מחזירה חוליית טווח הכוללת את המספר הקטן ביותר ואת המספר הגדול ביותר ברצף המספרים העוקבים החל‬
‫מהחוליה המתקבלת‪ .‬תזכורת ‪ -‬החוליה שמשתנה כאן‪ ,‬משתנה גם בפעולה העיקרית‬
‫‪//‬הנחה ‪ -‬החוליה היא מקום תקין ברשימה שאותחלה ומכילה מספרים שלמים שונים זה מזה וממוינים בסדר עולה‬
‫;‪RangeNode rangeNode = null; bool flag = true; int x_prev, min, max‬‬
‫;)(‪if (p != null) { x_prev = p.GetInfo‬‬
‫‪//‬אם יש לפחות ערך אחד ‪ -‬הוא הקטן ביותר ‪ -‬כיוון שהרשימה ממוינת‬
‫;)(‪min = x_prev; p = p.GetNext‬‬
‫‪//‬רצים על הרצף ‪ -‬עד שמגיעים לערך שלא עונה לרצף ‪ -‬לא עוקב ‪ -‬או לסוף הרשימה‬
‫{ )‪while (p != null && flag‬‬
‫{ )‪if (p.GetInfo() == x_prev + 1‬‬
‫} ;)(‪x_prev = p.GetInfo(); p = p.GetNext‬‬
‫};‪else flag = false‬‬
‫‪//‬האחרון ברצף הוא הגדול ביותר ‪ -‬כיוון שהרשימה ממוינת‬
‫} ;)‪max = x_prev; rangeNode = new RangeNode(min, max‬‬
‫} ;‪return rangeNode‬‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫‪4‬‬
‫‪2‬‬
‫א'‪/‬אדר‪/‬תשע"ה‬
‫פתרון – הפעולה העיקרית מחזירה רשימת טווחים ‪ -‬דרך ב'‬
‫)‪public static List<RangeNode> CreateRangeList(List<int> sourceList‬‬
‫{‬
‫‪//‬מחזירה את רשימת הטווחים של הרשימה המתקבלת‬
‫‪//‬הנחה ‪ -‬הרשימה אותחלה ומכילה מספרים שלמים שונים זה מזה וממוינים בסדר עולה‬
‫;)(>‪List<RangeNode> l_new = new List<RangeNode‬‬
‫;)(‪Node<RangeNode> p_new = l_new.GetFirst‬‬
‫;‪RangeNode x_new‬‬
‫;)(‪Node<int> p = sourceList.GetFirst‬‬
‫{ )‪while (p != null‬‬
‫;)‪x_new = SequenceToRangeNodeList(p‬‬
‫} )‪p_new = l_new.Insert(p_new, x_new‬‬
‫;‪return l_new‬‬
‫{‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫‪5‬‬
‫פתרון ‪ -‬סיבוכיות זמן הריצה‬
‫‪‬‬
‫‪‬‬
‫סיבוכיות זמן הריצה של הפעולות העזר של רצף בודד היא היא )‪,O(n‬‬
‫שכן היא סורקת באמצעות לולאת כל עוד את הרשימה ‪ -‬במקרה הגרוע ביותר ‪-‬‬
‫מתחילה עד סופה (רצף אחד)‪,‬‬
‫והיא משתמשת בפעולות הבסיסיות של חוליה שכולן ב‪.O(1) -‬‬
‫סיבוכיות זמן הריצה של הפעולה ‪ CreateRangeList‬היא לכאורה )‪ O(n2‬שכן‬
‫היא סורקת באמצעות לולאת כל עוד את הרשימה בדיוק פעם אחת‪ ,‬כאשר בכל‬
‫סריקה יש שימוש בפעולת העזר של רצף בודד שהיא‪ ,‬כאמור‪ ,‬ב‪ O(n) -‬ולכן‬
‫)‪.O(n) x O(n) = O(n2‬‬
‫אבל‪ ,‬בפועל אחרי כל ביצוע של פעולת העזר‪ ,‬ההתקדמות ברשימה היא רק בתוך‬
‫פעולת העזר‪ .‬כלומר יהיה בדיוק מעבר אחד על כל ערכי הרשימה‪ ,‬לא משנה איפה‬
‫תהיה ההתקדמות בסריקה בפעולת העזר או בפעולה ‪.CreateRangeList‬‬
‫בנוסף‪ ,‬יש שימוש בפעולה ‪ CreateRangeList‬בפעולות ממשק בסיסיות של‬
‫רשימה וחוליה שכולן ב‪.O(1) -‬‬
‫סה"כ סיבוכיות זמן הריצה של הפעולה ‪ CreateRangeList‬היא )‪.O(n‬‬
‫בניית רשימת רצפים ‪ -‬מתוך בגרות תש''ע‬
‫‪6‬‬
‫‪3‬‬