פרק - מדעי המחשב

‫יסודות מדעי המחשב ‪1‬‬
‫כל הזכויות שמורות למשרד החינוך‬
‫מטרת היחידה יסודות מדעי המחשב ‪ 1‬היא להכיר ולהקנות לתלמידים מושגי יסוד ועקרונות שעליהם‬
‫מושתתת הדיסציפלינה מדעי המחשב‪ .‬היא מהווה יחידת מבוא הן ליחידה יסודות מדעי המחשב ‪ ,2‬והן‬
‫לכל היחידות האחרות בתוכנית הלימודים‪ ,‬ובפרט ליחידה הרביעית‪ ,‬עיצוב תוכנה‪ .‬היחידה משלבת שני‬
‫ערוצים – ערוץ תיאורטי וערוץ יישומי‪ .‬הערוץ התיאורטי מתמקד בחשיבה אלגוריתמית‪ .‬היישום נעשה‬
‫בשפת התכנות ‪ ,Java‬שהיא שפה עילית מונחית עצמים‪.‬‬
‫הערוץ התיאורטי‬
‫היחידה יסודות מדעי המחשב ‪ 1‬מתמקדת בפתרון בעיות‪ .‬מנקודת מבט זו‪ ,‬אלגוריתם הוא פתרון לבעיה‪,‬‬
‫ותוכנית מחשב היא יישום ומימוש של הפתרון‪ .‬הערוץ התיאורטי שם דגש על ניתוח בעיה אלגוריתמית‪,‬‬
‫ועל פיתוח וניתוח אלגוריתמים‪ .‬בפרט‪ ,‬היחידה מתייחסת גם לנכונות של אלגוריתמים ויעילות של‬
‫אלגוריתמים ושמה דגש מיוחד על תבניות אלגוריתמיות‪ .‬התבניות האלגוריתמיות עוברות כחוט השני‬
‫ביחידה כולה‪ ,‬והבעיות המוצגות בה מיועדות בין השאר להדגמת השימוש בתבניות אלגוריתמיות‬
‫שונות‪ ,‬פיתוח מיומנויות הזיהוי של תבניות והשימוש בהן‪.‬‬
‫משום שהיחידה משתמשת בשפה מונחית עצמים‪ ,‬לא ניתן להתעלם‪ ,‬וגם אין סיבה להתעלם‪,‬‬
‫ממאפיינים מונחי עצמים של השפה ומהשפעותיהם על פיתוח האלגוריתמים‪ .‬כבר ביחידה יסודות מדעי‬
‫המחשב ‪ 1‬יכירו התלמידים מונחים בסיסיים בתכנון מונחה עצמים כגון מחלקה‪ ,‬עצם‪ ,‬ממשק‪ ,‬פעולות‬
‫ותכונות של עצם‪ ,‬אך לא יתבקשו להתמודד עם מידול והגדרת מחלקות‪ ,‬אלא ישתמשו במחלקות‬
‫מוגדרות‪ ,‬כקופסה שחורה‪ ,‬תוך הכרת הממשק שלהן‪ .‬היכרות זו תיעשה דרך המחלקות המוגדרות ב‪-‬‬
‫‪ Java‬למחרוזת ומערך‪ .‬פרק המבוא לעצמים יתמקד במחלקת המחרוזת‪ ,‬וידגים בעזרתה שימוש‬
‫במחלקות ובעצמים‪ .‬הפרק הבא יעסוק במערכים‪ ,‬תוך שימוש במחלקה המתאימה המוגדרת בשפה‪.‬‬
‫הערוץ היישומי‬
‫הכרת השפה המשמשת ליישום האלגוריתמים‪ ,‬תכלול גם התייחסות מפורשת )אך מוגבלת( למרכיבי‬
‫השפה המושרים על ידי מאפיינים של פרדיגמה מונחית עצמים‪ .‬בפרט‪ ,‬מחרוזות ומערכים יילמדו‬
‫כעצמים‪.‬‬
‫ספרי הלימוד אינם מחייבים סביבת עבודה מסוימת‪ ,‬והם בלתי תלויים בסביבת עבודה‪ .‬עם זאת‪,‬‬
‫מדריכי המעבדה יתייחסו כמובן לסביבת עבודה מסוימת‪ ,‬ובכך יהוו המלצה לא מחייבת למורים‪.‬‬
‫לעבודה עם שפת ‪ Java‬בחרנו בסביבת העבודה ‪ ,Dr. Java‬שפותחה באוניברסיטת ‪ Rice‬במיוחד לצורכי‬
‫הוראת קורס מבוא למדעי המחשב‪ .‬יתרונה של הסביבה הוא בפשטותה‪ ,‬ובכך שהיא מאפשרת עבודה‬
‫נוחה מאוד‪ ,‬ללא צורך לחשוף את התלמיד למידע שאינו רלבנטי עבורו‪ .‬בפרט‪ ,‬שלא כמו סביבות אחרות‪,‬‬
‫הסביבה מאפשרת עבודה ללא צורך בהגדרת פרויקט‪ ,‬דבר שאינו נדרש עבור שתי היחידות של יסודות‬
‫מדעי המחשב‪.‬‬
‫פרק ‪ – 1‬מבוא‬
‫מושגי תוכן‬
‫• מחשב‬
‫• קלט ופלט‬
‫• תוכנית מחשב‬
‫• תוכנה וחומרה‬
‫• מערכת הפעלה‬
‫• מבנה בסיסי של מחשב – אמצעי קלט ופלט‪ ,‬זיכרון‪ ,‬יחידת עיבוד מרכזית‬
‫• שפות תכנות – שפת מכונה ושפה עילית‬
‫• מהדר ותהליך הידור‬
‫• הרצת תוכנית‬
‫• ניפוי שגיאות‬
‫פרק ‪ – 2‬אלגוריתם‬
‫מושגי תוכן‬
‫• אלגוריתם‬
‫• בעיה אלגוריתמית‬
‫• ניתוח בעיה אלגוריתמית‬
‫• פעולות יסוד‬
‫• כתיבה בפסאודו‪-‬קוד‬
‫• ביצוע בתנאי‬
‫• ביצוע חוזר‬
‫מרכיבי שפה‬
‫אין בפרק זה‬
‫תבניות‬
‫אין בפרק זה‬
‫שאלות מייצגות‬
‫בעיה ‪1‬‬
‫שני מיכלים‪ ,‬מיכל א ומיכל ב‪ ,‬מכילים מספרים שונים של תפוזים‪ .‬סכום מספרי התפוזים בשני‬
‫המיכלים הוא זוגי‪.‬‬
‫פתחו אלגוריתם להעברת תפוזים בין המיכלים‪ ,‬כך שתפוזים יועברו פעם אחת בלבד‪ ,‬ולאחר ההעברה‬
‫יכילו המיכלים מספר שווה של תפוזים‪.‬‬
‫האלמנטים המודגמים בשאלה זו‪:‬‬
‫אלגוריתם‪ ,‬בעיה אלגוריתמית‪ ,‬פעולות יסוד‪ ,‬ניתוח בעיה אלגוריתמית‪ ,‬ביצוע בתנאי‪ ,‬כתיבה‬
‫בפסאודו‪-‬קוד‬
‫פתרון‪:‬‬
‫האלגוריתם‪:‬‬
‫חשב את מספר התפוזים להעברה‪ ,‬כחצי מההפרש בין מספרי התפוזים במיכלים‬
‫אם במיכל א יש יותר תפוזים‬
‫העבר ממיכל א למיכל ב תפוזים במספר המחושב‬
‫אחרת‬
‫העבר ממיכל ב למיכל א תפוזים במספר המחושב‬
‫בעיה ‪2‬‬
‫על השולחן שורת קלפים‪ .‬בשורה מספר אי‪-‬זוגי של קלפים‪ ,‬והקלף האמצעי הוא לבן‪ .‬כל הקלפים‬
‫שמשמאל לקלף הלבן שחורים וכל הקלפים שמימינו אדומים‪ .‬נתונות גם שתי סימניות‪ :‬סימניה‪1-‬‬
‫המוצבת על הקלף שבקצה השמאלי וסימניה‪ 2-‬המוצבת על הקלף שבקצה הימני‪.‬‬
‫פתחו אלגוריתם אשר מסדר את שורת הקלפים מחדש כך שכל הקלפים האדומים יהיו משמאל לקלף‬
‫הלבן וכל השחורים מימינו‪.‬‬
‫הפעולות המותרות לביצוע הן‪:‬‬
‫♦ הצבת סימניה מימין או משמאל לקלף שעליו היא מוצבת‪ .‬הצבת סימניה כוללת קריאת צבע הקלף‬
‫עליו היא מוצבת‪.‬‬
‫♦ החלפה זה בזה של מקומות הקלפים עליהם מוצבות הסימניות‪.‬‬
‫האלמנטים המודגמים בשאלה זו‪:‬‬
‫אלגוריתם‪ ,‬בעיה אלגוריתמית‪ ,‬פעולות יסוד‪ ,‬ניתוח בעיה אלגוריתמית‪ ,‬ביצוע חוזר‪ ,‬כתיבה‬
‫בפסאודו‪-‬קוד‬
‫פתרון‪:‬‬
‫האלגוריתם‪:‬‬
‫כל עוד הקלף עליו מוצבות הסימניות אינו לבן‬
‫החלף מקומות הקלפים עליהם מוצבות הסימניות‬
‫הצב סימניה‪ 1-‬על הקלף הבא מימין‬
‫הצב סימניה‪ 2-‬על הקלף הבא משמאל‬
‫פרק ‪ – 3‬אבני הבניין של אלגוריתמים‬
‫מושגי תוכן‬
‫• הוראות קלט‬
‫• הוראות פלט‬
‫• משתנים‬
‫• תיעוד‬
‫• פיתוח אלגוריתם בשלבים‪ :‬חלוקה לתתי‪-‬משימות‪ ,‬בחירת משתנים‪ ,‬כתיבת האלגוריתם ויישומו‬
‫• טיפוסי ערכים )שלם וממשי(‬
‫• אתחול משתנים‬
‫• הוראת השמה‬
‫• טבלת מעקב‬
‫• ניתוח אלגוריתם נתון‬
‫מרכיבי שפה‬
‫• מבנה תוכנית בשפת ‪Java‬‬
‫• הערות‬
‫• הצהרה על משתנים‬
‫• אתחול משתנים‬
‫• הוראות קלט ופלט‬
‫• הוראת השמה‬
‫• קבועים‬
‫תבניות‬
‫• החלפה בין שני ערכים‬
‫• הזזות )ליניארית ומעגלית( בסדרה בת שלושה‪/‬ארבעה איברים‬
‫פרק ‪ – 4‬מבוא לפיתוח אלגוריתמים‬
‫מושגי תוכן‬
‫• פיתוח אלגוריתם בשלבים )העמקה(‪:‬‬
‫‪ .1‬ניתוח ראשוני של הבעיה בעזרת דוגמאות‬
‫‪ .2‬פירוק הבעיה לתת‪-‬משימות‬
‫‪ .3‬בחירת משתנים‪ ,‬הגדרת תפקידיהם וטיפוסי הערכים שיישמרו בהם‪.‬‬
‫‪ .4‬כתיבת האלגוריתם‬
‫‪ .5‬יישום האלגוריתם בתכנית מחשב‬
‫‪ .6‬בדיקת נכונות עבור דוגמאות קלט מגוונות ומייצגות על ידי טבלת מעקב‬
‫‪ .7‬כתיבת התוכנית המלאה‪ ,‬ובדיקתה על ידי הרצה על דוגמאות קלט נוספות‬
‫• פעולות חלוקה בשלמים )מנה ושארית(‬
‫• טיפוס תווי‬
‫מרכיבי שפה‬
‫• הטיפוס ‪char‬‬
‫• המחלקה המתמטית ‪Math‬‬
‫• פעולות מהמחלקה המתמטית‪abs, min, max, sqrt, pow :‬‬
‫• אופן ביצוע פעולות חלוקה בשלמים ) ‪( % , /‬‬
‫• המרה )‪ (casting‬משלם לממשי‪ ,‬משלם לתווי‪ ,‬מתווי לשלם‪.‬‬
‫תבניות‬
‫• חלוקת כמות פריטים לקבוצות בגודל נתון )התחלקות מספר במספר(‬
‫• בדיקת זוגיות של מספר )רעיון בסיסי(‬
‫• פירוק מספר דו‪-‬ספרתי לספרותיו‬
‫• בניית מספר דו‪-‬ספרתי מספרות בודדות‬
‫פרק ‪ – 5‬ביצוע מותנה‬
‫מושגי תוכן‬
‫• הוראה לביצוע בתנאי הכוללת תנאי פשוט במבנה אם‪ ...‬אחרת‪...‬‬
‫• הצגת הוראה לביצוע בתנאי במבנה אם‪)...‬ללא החלק אחרת‪.(...‬‬
‫• תיאור משמעות קיום תנאי )ההערה שמלווה תנאי(‬
‫• טבלת מעקב עבור הוראה לביצוע בתנאי‬
‫• בחירת דוגמאות קלט מייצגות עבור הוראה לביצוע בתנאי‬
‫• הוראה לביצוע בתנאי שחלקיה כוללים מספר הוראות‬
‫• הוראה לביצוע בתנאי הכוללת תנאי מורכב‬
‫• ביטוי בוליאני‬
‫• הקשר וגם‬
‫• טבלת אמת של הקשר וגם‬
‫• הקשר או‬
‫• טבלת אמת של הקשר או‬
‫• קינון הוראות לביצוע בתנאי‬
‫• הוראה רב‪-‬ברירתית לביצוע בתנאי‬
‫מרכיבי שפה‬
‫• משפט …‪if…else‬‬
‫• פעולות השוואה על מספרים‬
‫• משפט ‪ if‬חלקי )ללא החלק של ה‪(else -‬‬
‫• פעולות השוואה על תווים‬
‫• סימן הפעולה של הקשר וגם &&‬
‫• סימן הפעולה של הקשר או | |‬
‫• ביטוי לחישוב במשפט פלט‬
‫• משפט …‪if… else… if‬‬
‫• משפט ‪switch‬‬
‫תבניות‬
‫• השוואה בין ערכים‬
‫• מציאת מקסימום בין שניים‪/‬שלושה ערכים‬
‫• סידור שניים‪/‬שלושה ערכים בסדר עולה‬
‫• בדיקת זוגיות של מספר )תבנית מלאה(‬
‫• בדיקת התחלקות של מספר במספר‬
‫• חלוקת כמות פריטים לקבוצות ‪ -‬הרחבה‬
‫פרק ‪ – 6‬נכונות אלגוריתמים‬
‫מושגי תוכן‬
‫• הגדרת נכונות‬
‫• דוגמאות קלט מייצגות‬
‫• זיהוי מטרת תוכנית‬
‫מרכיבי שפה‬
‫אין מרכיבי שפה בפרק זה‬
‫תבניות‬
‫אין תבניות חדשות בפרק זה‬
‫פרק ‪ – 7‬ביצוע חוזר‬
‫מושגי תוכן‬
‫• הוראה לביצוע חוזר‬
‫• הוראה לביצוע חוזר בין גבולות קבועים מראש‬
‫• גבול עליון וגבול תחתון‬
‫• הוראה לביצוע חוזר התלויה בביטוי בוליאני‬
‫• תנאי כניסה ללולאה‬
‫• זקיף‬
‫• לולאה אינסופית‬
‫• הוראה מקוננת לביצוע חוזר‬
‫• טיפוס בוליאני‬
‫• משתנה בוליאני‬
‫• קשר ‪not‬‬
‫• טבלת מעקב עבור הוראה לביצוע חוזר‬
‫מרכיבי שפה‬
‫• משפט ‪for‬‬
‫• משפט ‪while‬‬
‫• האופרטור =!‬
‫תבניות‪:‬‬
‫• תבנית מניה‬
‫• תבנית צבירה )חיבורית וכפלית(‬
‫• איסוף בקיזוז‬
‫• ממוצע‬
‫• מציאת מינימום‪/‬מקסימום בסדרה‬
‫• מציאת ערך נלווה למינימום‪/‬מקסימום בסדרה‬
‫• האם קיים איבר בסדרה המקיים תנאי?‬
‫• מציאת כל האיברים בסדרה המקיימים תנאי‬
‫• מעבר על זוגות סמוכים בסדרה‬
‫• האם כל הפריטים בסדרה מקיימים תנאי?‬
‫• פירוק מספר שלם לספרותיו‬
‫• בנייה מימין של מספר שלם מספרות בודדות‬
‫• בנייה משמאל של מספר שלם מספרות בודדות‬
‫פרק ‪ – 8‬יעילות של אלגוריתמים‬
‫מושגי תוכן‬
‫• יעילות של אלגוריתמים‬
‫• פעולות יסוד‬
‫• זמן ביצוע של אלגוריתם‬
‫• חיפוש סדרתי‬
‫• חיפוש בינארי‬
‫מרכיבי שפה‬
‫אין מרכיבים חדשים‬
‫תבניות‬
‫• חיפוש סדרתי‬
‫• חיפוש בינארי‬
‫פרק ‪ – 9‬מבוא לעצמים‬
‫מושגי תוכן‬
‫• מחלקה‬
‫• עצם‬
‫• מופע עצם‬
‫• שימוש בתכונות של עצמים‬
‫• שימוש בפעולות של עצמים‬
‫• ממשק‬
‫• הדגמה של עבודה עם מחלקות ועצמים על ידי המחלקה מחרוזת‬
‫• פונקציות‬
‫• פרמטרים‬
‫מרכיבי שפה‬
‫• סימון הנקודה‬
‫• תכונות של עצם מהמחלקה מחרוזת‪length :‬‬
‫• פעולות של עצם מהמחלקה מחרוזת‪,toLowerCase ,substring ,indexOf ,charAt :‬‬
‫‪.compareTo ,equals ,toUpperCase‬‬
‫• פעולות נוספות על מחרוזות‪ :‬שרשור )‪(+‬‬
‫תבניות‬
‫אין תבניות חדשות בפרק זה‬
‫פרק ‪ – 10‬מערכים‬
‫מושגי תוכן‬
‫• מערך‬
‫• איבר במערך‬
‫• מציין של איבר‬
‫• מערך כעצם‬
‫• יעילות מקום‬
‫מרכיבי שפה‬
‫• הקצאת מערך‬
‫• תכונת מערך‪length :‬‬
‫• מחלקת מספרים אקראיים‬
‫תבניות‬
‫• מערך מונים‬
‫• מערך צוברים‬
‫• מציאת שכיח‬
‫• הזזה מעגלית בסדרה‬
‫• הזזה של תת‪-‬סדרה‬
‫• הפיכת סדר האיברים בסדרה‬
‫• הגרלת מספר‬
‫יסודות מדעי המחשב ‪2‬‬
‫יסודות מדעי המחשב ‪ 2‬היא יחידת המשך ליסודות מדעי המחשב ‪ .1‬היא מתבססת על מה שנלמד‬
‫ביסודות מדעי המחשב‪ ,‬מחד‪ ,‬ומהווה שער ליחידה הרביעית‪ ,‬עיצוב תוכנה‪ ,‬מאידך‪ .‬כמו יסודות מדעי‬
‫המחשב ‪ 1‬אף היא משלבת שני ערוצים – ערוץ תיאורטי וערוץ יישומי‪ .‬מטרתה של היחידה היא‬
‫להעמיק בשני הערוצים‪ ,‬ובפרט להעמיק עוד בחשיבה אלגוריתמית‪ ,‬הכרת תבניות אלגוריתמיות‪,‬‬
‫והיכרות עם הפרדיגמה מונחית העצמים‪.‬‬
‫ביחידה זו כבר יידרשו התלמידים למידול של עולם ולהגדרת מחלקה‪ ,‬אך כיחידת מבוא‪ ,‬רמת המידול‬
‫הנדרשת תהיה מוגבלת‪ .‬לא תהיה כלל התייחסות ליחסים בין מחלקות שונות‪ ,‬והבעיות ידרשו מידול‬
‫מחלקה בודדת‪ .‬המטרה היא מצד אחד להרגיל את התלמידים לחשוב בצורה מונחית עצמים על מנת‬
‫להכינם ליחידה עיצוב תוכנה‪ ,‬ומצד שני לפתח את ההיבט האלגוריתמי שמהווה את הבסיס בכל סוג של‬
‫תכנות )פרוצדורלי‪ ,‬פונקציונלי‪ ,‬מונחה עצמים וכו'(‪ .‬ההיבט האלגוריתמי בא לידי ביטוי הן בתוכנית‬
‫המשתמשת במחלקה המוגדרת והן בפעולות של המחלקה‪ .‬המגבלה על מידול מחלקה בודדת‪ ,‬מתאימה‬
‫לתחום הדיון של היחידות יסודות מדעי המחשב ‪ 1‬ו‪ ,2-‬המתמקדות בפתרון בעיות אלגוריתמיות ולא‬
‫בהתמודדות עם מורכבות מערכתית‪ ,‬התמודדות העומדת במרכזה של היחידה הרביעית‪ ,‬עיצוב תוכנה‪.‬‬
‫מבחינה יישומית‪ ,‬המגבלה של עבודה עם מחלקה בודדת מאפשרת עבודה עם קובץ בודד‪ ,‬ללא צורך‬
‫בהגדרת פרוייקט‪.‬‬
‫ביחידה זו שלושה פרקים‪ .‬הפרק הראשון מרחיב בכיוון של חשיבה מונחית עצמים‪ .‬בפרק זה כבר ילמדו‬
‫התלמידים להגדיר מחלקה )שלא כמו ביסודות ‪ ,1‬שם למדו להשתמש במחלקה מוגדרת( ולהשתמש בה‪.‬‬
‫התלמידים יכירו מושגים בסיסיים בתכנות מונחה עצמים כגון תכונות )בסיסיות ומורכבות( ופעולות של‬
‫עצם‪ ,‬מאפייני נגישות‪ ,‬פעולה בונה וכו'‪ .‬הפרק יישען על הידע הנלמד ביחידה הקודמת‪ ,‬וכך‪ ,‬למשל‪,‬‬
‫תהיה התייחסות למערך כתכונה ואל מערך של עצמים‪ .‬הפרק השני מרחיב בכיוון של חשיבה‬
‫אלגוריתמית ומציג תבניות מורכבות כגון מיון ומיזוג‪ ,‬שילוב תבניות )שרשור‪ ,‬הכלה ושזירה(‪ ,‬ומבנה‬
‫נתונים מעט מתקדם יותר של מערך דו‪-‬מימדי‪ .‬הפרק השלישי מוקדש לפתרון בעיות ומשלב אלמנטים‬
‫משני הפרקים הקודמים לו‪ ,‬משום שבפתרון הבעיות יש גם מרכיב של מידול וגם מרכיב של חשיבה‬
‫אלגוריתמית משמעותית‪ .‬אין בפרק זה מרכיבי ידע חדשים‪ ,‬והוא מתמקד ביישום כל החומר הנלמד‬
‫בשתי היחידות באופן משולב לפתרון בעיות אלגוריתמיות‪.‬‬
‫פרק ‪ – 1‬מחלקות ועצמים‪ :‬הרחבה והעמקה‬
‫מושגי תוכן‬
‫• הגדרת מחלקה‬
‫• מאפייני נגישות )‪(public, private‬‬
‫• הגדרת תכונות של עצמים )‪(data member‬‬
‫• הגדרת פעולות של עצמים )‪(methods‬‬
‫• פעולות גישה )‪(get, set‬‬
‫• פעולות בונות )ללא העמסה(‬
‫• תיעוד מחלקה‬
‫• תכונות מורכבות של עצמים )מערך כתכונה(‬
‫• מבני נתונים בסיסיים של עצמים )מערך(‬
‫• פונקציות ופרמטרים – העמקה‬
‫• עצם כפרמטר‬
‫מרכיבי שפה‬
‫• הגדרת מחלקה )‪ (class‬על כל מרכיביה – תכונות ופעולות בסיסיות‪ ,‬שימוש ב‪.this-‬‬
‫• שימוש במחלקה שהוגדרה‪.‬‬
‫תבניות‪:‬‬
‫אין תבניות חדשות בפרק זה‬
‫פרק ‪ – 2‬תבניות אלגוריתמיות‬
‫פרק זה מודגש להעמקה אלגוריתמית‪ ,‬דרך תבניות‪ .‬בפרק זה יש שימוש במחלקות )שהרי בפרק הקודם‪,‬‬
‫הפרק הראשון של יסודות ‪ ,2‬כבר עסקו התלמידים בהגדרת מחלקה(‪ ,‬אבל הדגש הוא על הצד‬
‫האלגוריתמי‪ .‬הצד האלגוריתמי יכול להתבטא הן בתוכנית הראשית‪ ,‬והן בפעולות של המחלקה‬
‫המוגדרת )אם יש כזאת(‪.‬‬
‫מושגי תוכן‬
‫• מיון בחירה‬
‫• מיזוג‬
‫• חיפוש סדרתי במערך‬
‫• חיפוש בינארי במערך‬
‫• מערך דו‪-‬מימדי‬
‫• מערך של מערכים‬
‫• הרכבת תבניות )שרשור‪ ,‬הכלה‪ ,‬שזירה(‬
‫• שגיאות נפוצות בהרכבת תבניות ותיקונן‬
‫מרכיבי שפה‬
‫• הגדרת מערך דו‪-‬מימדי ושימוש בו‬
‫תבניות‬
‫• חיפוש סדרתי‬
‫• חיפוש בינארי‬
‫• מיון בחירה‬
‫• מיזוג‬
‫• קודם‪-‬עוקב‬
‫פרק ‪ – 3‬פתרון בעיות‬
‫הפרק עוסק בפתרון בעיות‪ ,‬שלהן גם צד אלגוריתמי וגם צד של מידול והגדרת מחלקה‪ .‬לא יהיו בו‬
‫למעשה מושגים חדשים ותבניות חדשות‪ ,‬אלא התמקדות בפתרון בעיות בלבד‪ .‬להלן חמש בעיות‬
‫המייצגות את הנקודה אליה יש לשאוף בסוף "יסודות ‪."2‬‬
‫שאלות מייצגות‬
‫בעיה ‪1‬‬
‫בסוכנות הנסיעות "שלם וסע" מארגנים טיולים לחו"ל‪ .‬הסוכנות מציעה ‪ 100‬טיולים‪ ,‬שלכל אחד מהם‬
‫מספר בין ‪ 1‬ל‪ .100-‬לכל טיול יכולים להרשם עד ‪ 50‬נוסעים‪ .‬נוסע יכול להירשם לטיול רק אם יש מקום‬
‫בטיול‪.‬‬
‫פתחו ויישמו אלגוריתם לניהול סוכנות הנסיעות‪ .‬האלגוריתם ירשום אנשים על פי שמם לטיולים‬
‫אליהם הם מבקשים להירשם ויציג לבסוף את רשימת הטיולים ממויינת לפי מספר האנשים בכל טיול‪.‬‬
‫אם ישנם שני טיולים עם אותו מספר נרשמים הם יוצגו לפי מספרם הסידורי‪ .‬עבור כל טיול יוצגו גם‬
‫האנשים המשתתפים בטיול‪.‬‬
‫מאפייני הבעיה‪ :‬מערך של עצמים‪ ,‬מערך כתכונה של עצם‪ ,‬מיון‬
‫פתרון‪:‬‬
‫*‪/‬‬
‫מחלקת טיול‬
‫‪*/‬‬
‫‪class Trip‬‬
‫{‬
‫משתני המחלקה ‪//‬‬
‫קבוע‪ :‬מספר נוסעים‬
‫‪private final int MAX_PASSENGER_PER_TRIP =50; //‬‬
‫מספר טיול ‪//‬‬
‫;‪private int tripNum‬‬
‫מספר נרשמים ‪//‬‬
‫;‪private int passengersNum = 0‬‬
‫שמות הנרשמים לטיול ‪//‬‬
‫;‪private String[] passengers‬‬
‫פעולה בונה ‪//‬‬
‫)‪public void Trip(int tripNum‬‬
‫{‬
‫;]‪this.passengers = new String[MAX_PASSENGER_PER_TRIP‬‬
‫;‪this.tripNum = tripNum‬‬
‫}‬
// ‫פעולות גישה‬
public int getTripNum()
{
return this.tripNum;
}
public int getNumberOfPassengers()
{
return this.passengersNum;
}
// ‫הפעולה מדפיסה את שמות המשתתפים בטיול‬
public void printPassengers()
{
int i;
for (i= 0; i < this.passengersNum; i++)
{
System.out.println(passengers[i]);
}
}
// ‫הפעולה מוסיפה נוסע לטיול‬
// ‫ומחזירה ערך אמת אם יש מקום בטיול ושקר אחרת‬
public boolean addPassenger(String passenger)
{
if (this.passengersNum < this.MAX_PASSENGER_PER_TRIP-1)
{
this.passengers[this.passengersNum] = passenger;
this.passengersNum++;
return true;
} // if
return false;
} // addPassenger
}// class Trip
/*
‫מחלקה ראשית‬
*/
public class Main
{
public static void main(String[] args)
{
//
‫הגדרת והקצאת משתנים‬
final int TRIPS_NUM = 100;
// ‫ מספר טיולים‬:‫קבוע‬
Trip[] tripsList = new Trip[TRIPS_NUM];
// ‫מערך הטיולים‬
int passenger, trip;
// ‫ נוסע‬/ ‫מספר טיול מבוקש‬
String passengerName;
// ‫שם נוסע‬
int passengerNum;
// ‫מספר הנוסעים‬
int passengerNumberOfTrips;
// ‫מספר הטיולים להם מבקש הנוסע להירשם‬
int tripNum;
int passTrips;
int num;
int i,r;
//
‫הקצאת מערך הטיולים‬
for (i = 0; i < TRIPS_NUM; i++)
{
tripsList[i] = new Trip(i + 1); // 1 ‫ כיוון שמספור הטיולים החל מ‬+1
}
// ‫קלט מספר הנוסעים‬
passengerNum = InputRequestor.requestInt("Insert the number of
people");
for (passenger = 0; passenger < passengerNum; passenger++)
{
passengerName = InputRequestor.requestString("Insert the passenger
mame");
passengerNumberOfTrips = InputRequestor.requestInt("Insert the
number of trips the passenger wants to subscribe to");
for (trip = 0; trip < passengerNumberOfTrips; trip++)
{
tripNum = InputRequestor.requestInt("Insert the trip number);
tripsList[tripNum-1].addPassenger(passengerName);
} // for trip
‫‪} // for passenger‬‬
‫סדר את הטיולים לפי כמות הנרשמים ‪//‬‬
‫;‪Trip temp‬‬
‫)‪for (i = 0; i < tripsList.length - 1; i++‬‬
‫{‬
‫)‪for (r = i + 1; r < tripsList.length; r++‬‬
‫{‬
‫=< )(‪if (tripsList[i].getNumberOfPassengers‬‬
‫))(‪tripsList[r].getNumberOfPassengers‬‬
‫{‬
‫החלף ‪//‬‬
‫;]‪temp = tripsList[i‬‬
‫;]‪tripsList[i] = tripsList[r‬‬
‫;‪tripsList[r] = temp‬‬
‫‪} // if‬‬
‫‪} // for r‬‬
‫‪} // for i‬‬
‫הדפס את הטיולים לפי מספר המשתתפים ואת המשתתפים בכל טיול ‪//‬‬
‫)‪for (i = 0; i < tripsList.length ; i++‬‬
‫{‬
‫‪System.out.println("Trip " + tripsList[i].getTripNum() + " has "+‬‬
‫;)"‪tripsList[i].getNumberOfPassengers() + " passengers‬‬
‫;)(‪tripsList[i].printPassengers‬‬
‫‪} // for‬‬
‫‪} // main‬‬
‫‪} // class Main‬‬
‫בעיה ‪2‬‬
‫באולימפיאדת הארנבים מתקיימת תחרות ריצה בארבעה מצבים שונים‪ :‬ריצה לגזר‪ ,‬ריצה לחסה‪ ,‬ריצה‬
‫לברוקולי‪ ,‬ריצה לתירס‪ .‬באולימפיאדה מחולקות שתי מדליות זהב‪ .‬את הראשונה מקבל הארנב שהזמן‬
‫הממוצע שלו בכל התחרויות הוא המהיר ביותר‪ .‬את השנייה מקבל הארנב שזמן הריצה שלו באחת‬
‫התחרויות הוא המהיר ביותר‪.‬‬
‫פתחו ויישמו אלגוריתם העוזר למארגני התחרות לבחור את המנצחים‪ .‬האלגוריתם יקלוט רשימה של‬
‫שמות הארנבים יחד עם זמני הריצה שלהם לכל מקצה וידפיס את רשימת הארנבים והתוצאה הטובה‬
‫ביותר לכל ארנב‪ ,‬מסודרת מהתוצאה הטובה הנמוכה ביותר אל התוצאה הטובה הגבוהה ביותר‪ ,‬את‬
‫רשימת הארנבים והתוצאה הממוצעת של כל ארנב‪ ,‬מסודרת מהתוצאה הממוצעת הנמוכה ביותר אל‬
‫התוצאה הממוצעת הגבוהה ביותר‪ ,‬ואת מקבלי מדליות הזהב‪ .‬שימו לב שאם לשני ארנבים יש את אותו‬
‫זמן ריצה הם יודפסו לפי הסדר האלפביתי של שמותיהם‪.‬‬
‫מאפייני הבעיה‪ :‬מערך של עצמים‪ ,‬מערך כתכונה‪ ,‬תבנית מיון‪ ,‬תבנית מינימום‪ ,‬תבנית ממוצע‬
‫פתרון‪:‬‬
‫התוכנית בשפת ‪:Java‬‬
‫*‪/‬‬
‫מחלקת ארנב אולימפי‬
‫‪*/‬‬
‫‪class RabbitOlympics‬‬
‫{‬
‫משתני המחלקה ‪//‬‬
‫שם הארנב ‪//‬‬
‫;‪private String name‬‬
‫תוצאות זמני הארנב במרוצים שונים ‪//‬‬
‫;‪private float[] times‬‬
‫פעולה בונה ‪//‬‬
‫)‪public RabbitOlympics(String name, float[] times, int numOfRaces‬‬
‫{‬
‫;‪this.name = name‬‬
‫;]‪this.times = new float[numOfRaces‬‬
‫)‪for (int i=0; i<times.length; i++‬‬
‫{‬
‫;]‪this.times[i] = times[i‬‬
‫}‬
‫}‬
‫)(‪public string getName‬‬
‫{‬
‫;‪return this.name‬‬
‫}‬
‫הפעולה מוצאת את הזמן המינימלי שהושג ‪//‬‬
‫)(‪public float getBestResult‬‬
‫{‬
float min=this.times[0];
for (int i=1; i<times.length; i++)
{
if (this.times[i] < min)
{
min = this.times[i];
}
} // for i
return min;
} // getBestResult
// ‫הפעולה מחשבת את הזמן הממוצע של הארנב בכל המרוצים‬
public float getAverageResult()
{
float sum = 0;
int i;
for (i = 0; i < this.times.length; i++)
{
sum += this.times[i];
}
return (sum/i);
}
} // class RabbitOlympics
/*
‫מחלקה ראשית‬
*/
public class Main
{
public static void main(String[] args)
{
// ‫הגדרת והקצאת משתנים‬
int numOfRabbits;
// ‫מספר הארנבים‬
RabbitOlympics[] rabbits;
// ‫מערך הארנבים‬
String rabbitStr;
// ‫קלט שם הארנב‬
final int NUM_RACES=4;
// ‫קבוע – מספר המרוצים‬
float[] rabbitScoresArray;
// ‫מערך זמני המרוצים לארנב‬
numOfRabbits = InputRequestor.requestInt(“Insert number of
rabbits”);
rabbits = new RabbitOlympics[numOfRabbits];
rabbitScoresArray = new float[NUM_RACES];
//
‫קלט‬
for (int i = 0; i <
numOfRabbits; i++)
{
// ‫ שם ורשימת זמני המרוצים‬:‫עבור כל ארנב‬
rabbitStr = InputRequestor.requestString(“Insert a rabbit
name”);
for (int scoreIndex = 0; scoreIndex < NUM_RACES;
scoreIndex++)
{
rabbitScoresArray[scoreIndex] =
InputRequestor.requestInt(“Insert the rabbit score”);
}
// ‫הקצאת הארנב במערך‬
rabbits[i] = new RabbitOlympics(rabbitStr,
rabbitScoresArray);
};
RabbitOlympics bestGold;
// ‫מחזיק מדלית הזמן הטוב ביותר‬
RabbitOlympics averageGold;
// ‫מחזיק מדלית הזמן הממוצע הטוב ביותר‬
RabbitOlympics temp;
// ‫משתנה עזר למיון‬.
// ‫מיון המערך על פי תוצאות טובות ביותר‬
for (int i=0; i<rabbits.length-1; i++)
{
for (int j=i+1; j<rabbits.length; j++)
{
if (rabbits[i].getBestResult() > rabbits[j].getBestResult())
{
// ‫החלפה‬
temp = rabbits[i];
rabbits[i] = rabbits[j];
rabbits[j] = temp;
}
else if (rabbits[i].getBestResult() ==
rabbits[j].getBestResult()
&&(rabbits[i].getName().compareTo(rabbits[j].getName()) > 0))
{
temp = rabbits[i];
rabbits[i] = rabbits[j];
rabbits[j] = temp;
}
} // for j
} // for i
// ‫הצבת הארנב הזוכה לפי זמן ריצה‬
bestGold = rabbits[0];
//
‫פלט התוצאות ממוינות לפי זמן ריצה‬
System.out.println("Best results are:");
for (int i=0; i<rabbits.length; i++)
{
System.out.println("name: "+rabbits[i].getName() + " Time: " +
rabbits[i].getBestResult());
}
// ‫מיון המערך לפי ממוצע זמנים‬
for (int i=0; i<rabbits.length-1; i++)
{
for (int j=i+1; j<rabbits.length; j++)
{
if (rabbits[i].getAverageResult() >
rabbits[j].getAverageResult())
{
//‫החלפה‬
temp = rabbits[i];
rabbits[i] = rabbits[j];
rabbits[j] = temp;
}
else if (rabbits[i].getAverageResult() ==
rabbits[j].getAverageResult() &&
(rabbits[i].getName().compareTo(rabbits[j].getName()) > 0))
‫{‬
‫;]‪temp = rabbits[i‬‬
‫;]‪rabbits[i] = rabbits[j‬‬
‫;‪rabbits[j] = temp‬‬
‫}‬
‫‪} // for j‬‬
‫‪} // for i‬‬
‫הצבת הארנב הזוכה לפי זמן ממוצע ‪//‬‬
‫;]‪averageGold = rabbits[0‬‬
‫פלט התוצאות ממוינות לפי זמן ממוצע‬
‫‪//‬‬
‫;)"‪System.out.println("Average results are:‬‬
‫)‪for (int i=0; i<rabbits.length; i++‬‬
‫{‬
‫‪System.out.println("name: "+rabbits[i].getName() + " Time: " +‬‬
‫;))(‪rabbits[i].getAverageResult‬‬
‫}‬
‫‪System.out.println("The best gold medalist is:" +‬‬
‫;))(‪bestGold.getName‬‬
‫‪System.out.println("The average gold medalist is:" +‬‬
‫;))(‪averageGold.getName‬‬
‫‪}//main‬‬
‫‪}// class Main‬‬
‫בעיה ‪3‬‬
‫חנות הדיסקים דיסקו שכרה יועץ על מנת לארגן מחדש את החנות‪ .‬היועץ המליץ לארגן את קטלוג‬
‫הדיסקים בחנות באופן הבא‪ :‬היוצרים יהיו מסודרים בסדר אלפביתי ולכל יוצר קיימת רשימת‬
‫הדיסקים שלו‪ ,‬מסודרת אף היא בסדר אלפביתי‪.‬‬
‫הגדירו מחלקה המייצגת את הקטלוג המוצע‪ .‬כללו בה פעולה המקבלת שם של יוצר ושם של דיסק‬
‫ובודקת האם הוא נמצא בחנות‪.‬‬
‫מאפייני הבעיה‪ :‬חיפוש )סידרתי או בינארי( כפול במערך דו‪-‬מימדי‪.‬‬
:‫פתרון‬
‫ מבוססת על חיפוש סדרתי‬:‫גירסה ראשונה‬
/*
‫מחלקת קטלוג דיסקים‬
*/
class DiskStore
{
// ‫משתני המחלקה‬
private String[][] artistsDisks; // ‫מאגר הדיסקים‬
// ‫ שומרת עבור כל אמן את רשימת הדיסקים שלו‬:‫פעולה בונה‬
public DiskStore(String[] artists)
{
int artistIndex;
int diskIndex;
this.artistsDisks = new String[artists.length][];
for (artistIndex = 0; artistIndex < artists.length; artistIndex++)
{
String[] disks = artists[artistIndex].split(" ");
this.artistsDisks[artistIndex] = new String[disks.length];
this.artistsDisks[artistIndex][0] = disks[0]; // ‫שם האמן בתא הראשון‬
// ‫שאר התאים – רשימת הדיסקים של האמן‬
for (diskIndex=1; diskIndex < disks.length; diskIndex++)
{
this.artistsDisks[artistIndex][diskIndex] = disks[diskIndex];
} // for diskIndex
} // for artistIndex
} // DiskStore
// ‫הפעולה בודקת האם דיסק של אמן קיים בחנות – חיפוש סדרתי‬
public boolean checkDisk (String artistName, String diskName)
{
int artistIndex;
int diskIndex;
for (artistIndex = 0; artistIndex < this.artistsDisks.length;
artistIndex++)
{
if (artistName.equals(this.artistsDisks[artistIndex][0]))
{
for (diskIndex = 1; diskIndex <
this.artistsDisks[artistIndex].length; diskIndex++)
{
if (diskName.equals(this.artistsDisks[artistIndex][diskIndex]))
{
return true;
}
} // for diskIndex
} // if artist
} // for artistIndex
return false;
} // checkDisk
} // class DiskStore
/*
‫מחלקה ראשית‬
*/
public class Main
{
public static void main(String[] args)
{
// ‫הגדרת והקצאת משתנים‬
DiskStore ourStore;
// ‫קטלוג הדיסקים‬
String artistName;
// ‫שם הזמר‬
String[] artists;
// ‫מחרוזת דיסקים לזמר‬
String diskName;
// ‫שם דיסק‬
int num;
// ‫מספר הזמרים‬
// ‫ מספר הזמרים‬:‫קלט‬
num=InputRequestor.requestInt("Insert number of artists");
artists = new String[num];
// ‫קלט – שם ודיסקים לכל זמר‬
for (int i = 0; i < num; i++)
{
artists[i] = InputRequestor.requestString("Insert the artist name
and his/her disks");
}
// ‫הקצאת מערך הקטלוג‬
ourStore = new DiskStore(artists);
// ‫קלט – שם זמר ודיסק‬
artistName = InputRequestor.requestString("Insert the name of the artist
you are looking for");
diskName = InputRequestor.requestString("Insert the name of the disk you
are looking for");
// ‫פלט – האם הדיסק של האמן קיים במאגר‬
if (ourStore.checkDisk(artistName,diskName))
{
System.out.println("The disk "+diskName+" of artist "+artistName+" is
in the store");
}
else
{
System.out.println("The disk "+diskName+" of artist "+artistName+" is
not in the store");
}
}// main
} // Class Main
‫ מוחלפת‬DiskStore ‫ של המחלקה‬CheckDisk ‫ הפעולה‬.‫ מבוססת על חיפוש בינארי‬:‫גירסה שנייה‬
.checkArtist ‫ הנקראת‬,‫ ונעזרת בפעולה חדשה של המחלקה‬,‫בגירסה אחרת‬
// ‫הפעולה מחפשת האם הזמר נמצא במערך על ידי חיפוש בינרי‬
private int checkArtist (String artist)
{
int high = this.artistsDisks.length;
int low = -1;
int mid;
while (high -low >1)
{
mid = (high + low) / 2;
if (this.artistsDisks[mid][0].compareTo(artist) > 0)
{
high = mid;
}
else
{
low = mid;
}
} // while
if (low == -1 || this.artistsDisks[low][0].equals(artist) == false)
{
return -1;
}
return low;
} // checkArtist
// ‫הפעולה מחפשת האם הדיסק נמצא במערך על ידי חיפוש בינרי‬
public boolean checkDisk (String artist, String disk)
{
int artistPlace;
int high, low, mid;
artistPlace=this.checkArtist(artist);
if (artistPlace == -1)
{
return false;
}
high = this.artistsDisks[artistPlace].length;
low = -1;
while (high -low >1)
{
mid = (high+low)/2;
if (this.artistsDisks[artistPlace][mid].compareTo(disk) > 0)
‫{‬
‫;‪high = mid‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪low = mid‬‬
‫}‬
‫‪} // while‬‬
‫== )‪if (low == -1 || (this.artistsDisks[artistPlace][low].equals(disk‬‬
‫))‪false‬‬
‫{‬
‫;‪return false‬‬
‫}‬
‫;‪return true‬‬
‫‪} // checkDisk‬‬
‫בעיה ‪4‬‬
‫נתון מערך דו מימדי בגודל ‪ 12X12‬המכיל מספרים שלמים מ‪ 1 -‬עד ‪) 30‬כולל( במערך יש "רביעייה ‪"k‬‬
‫אם המספר ‪ k‬מופיע במערך ב‪ 4 -‬תאים של תת‪-‬מערך בגודל ‪.2X2‬‬
‫לדוגמה‪ ,‬לפניכם מערך בגודל ‪ .5X5‬במערך יש "רביעייה ‪:"9‬‬
‫‪3 2 2 8‬‬
‫‪1‬‬
‫‪9 9 6 1‬‬
‫‪2‬‬
‫‪12 9 9 1 4‬‬
‫‪17 6 8 5 2‬‬
‫‪3 5 7 1‬‬
‫‪1‬‬
‫הגדירו מחלקה לייצוג מערך דו‪-‬מימדי כפי שתואר לעיל‪ ,‬וכללו בה את הפעולות הבאות‪:‬‬
‫‪ (1‬פעולה למציאת "רביעייה ‪ ."k‬הפעולה תקבל את המספר ‪ k‬ותחזיר ‪ TRUE‬אם ישנה "רביעייה‬
‫‪ "k‬במערך ו‪ FALSE-‬אחרת‪.‬‬
‫‪ (2‬פעולה למציאת והדפסת המספר ‪ k‬הגדול ביותר עבורו יש "רביעייה ‪ "k‬במערך‪ .‬אם לא נמצאה‬
‫רביעייה ‪ k‬במערך תדפיס הפעולה הודעה מתאימה‪ .‬יש להשתמש בפעולה שנכתבה בסעיף א‪.‬‬
.‫ קינון של פעולה בתוך פעולה‬,‫ תבנית מקסימום‬,‫מימדי‬-‫ חיפוש במערך דו‬:‫מאפייני הבעיה‬
:‫פתרון‬
/*
‫מחלקת מערך דו מימדי למספרים שלמים‬
*/
class int2DimArray
{
// ‫משתני המחלקה‬
private int[][] array;
// ‫המערך‬
private int numRow;
private int numCol;
// ‫פעולה בונה‬
public int2DimArray(int[][] array, int numRow, int numCol)
{
this.array = new int [numRow] [numCol];
for (int i=0; i< numRow; i++)
{
for (int j=0; j< numCol; j++)
{
this.array[i][j] = array[i][j];
}
// for i
} // for j
this.numRow = numRow;
this.numCol = numCol;
} // int2DimArray
// ‫ במערך ושקר אחרת‬k ‫הפעולה מחזירה אמת אם נמצאת רביעייה‬
public boolean find4K(int k)
{
int i,r;
for
(i = 0; i <
this.numRow - 1; i++)
{
for (r = 0; r < this.numCol - 1 ; r++)
{
if ( (this.array[i][r] == k) && (this.array[i+1][r] == k) &&
(this.array[i][r+1] == k) && (this.array[i+1][r+1] == k) )
{
return true;
} // if
} // for r
} // for i
return false;
} // find4k
public int findBiggestK ()
{
int i,r;
int max = 0;
int maxK = -1;
boolean found = false;
//
‫מציאת המספר הגדול ביותר במטריצה‬
(i = 0; i <
for
this.numRow ; i++)
{
for (r = 0; r < this.numCol; r++)
{
if (this.array[i][r] > max)
{
max = this.array[i][r];
}
} // for r
} // for i
// ‫חיפוש האם קיימת רביעייה עם אחד מהמספרים החל מהמספר הגדול במטריצה‬
i = max;
while (found == false)
{
if (this.find4K(i) == true)
{
maxK = i;
found = true;
}
else
{
i--;
}
} // while
return maxK;
} // findBiggestK
}// class int2dimArray
/*
‫מחלקה ראשית‬
*/
public class Main
{
public static void main(String[] args)
{
// ‫הגדרת משתנים‬
final int SIZE = 12;
int[][] intArray;
// ‫מערך הקלט‬
int2DimArray twoDimArrayObject;
// ‫אובייקט המערך‬
int k;
int col,row;
int size;
int i,r;
int counter;
// ‫קלט למערך והקצאת האובייקט‬
intArray = new int[SIZE][SIZE];
for
(i = 0; i <
intArray.length; i++)
{
System.out.println (“insert the numbers of the next row”);
for (r = 0; r < intArray[i].length; r++)
{
intArray[i][r] = InputRequestor.requestInt("Insert a number: ");
} // for r
} // for i
‫;)‪twoDimArrayObject = new int2DimArray (intArray, SIZE, SIZE‬‬
‫קלט מספר וחיפוש רביעיה שלו ‪//‬‬
‫;)" ‪k = InputRequestor.requestInt("Insert k‬‬
‫))‪if (twoDimArrayObject.find4K(k‬‬
‫{‬
‫;)‪System.out.println("Found quartet of " + k‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;)‪System.out.println("Couldn't find quartet of " + k‬‬
‫}‬
‫חיפוש והדפסת הרביעיה הגדולה במערך ‪//‬‬
‫‪System.out.println("The biggest quartet is of "+‬‬
‫;))(‪twoDimArrayObject.findBiggestK‬‬
‫‪} // main‬‬
‫‪}// class Main‬‬
‫בעיה ‪ – 5‬קווי אוטובוס‬
‫פתחו ויישמו אלגוריתם המקבל כקלט מספר שלם חיובי ‪ ,N‬שמבטא מספר קווי אוטובוס‪ ,‬ואחריו ‪N‬‬
‫קווים )קו‪ ,1-‬קו‪ ... ,2-‬קו‪ ,(N-‬כאשר עבור כל קו יש בקלט את שם הקו )…‪ (line1,line2‬ואת התחנות‬
‫בהן עובר הקו – מתוארות על ידי ‪ 10‬מספרים שונים‪ ,‬בסדר עולה‪ ,‬שמבטאים מספרי תחנות‪ .‬בסה"כ‬
‫במערכת ישנן ‪ 100‬תחנות )הממוספרות ‪ .(100-1‬על האלגוריתם לתת את הפלטים הבאים‪:‬‬
‫‪ .1‬התחנה )הספרה( המשותפת למספר מירבי של אוטובוסים‪.‬‬
‫‪ .2‬מספר התחנות המשותפות לקווים ‪ 1‬ו‪.2-‬‬
‫‪ .3‬הודעה האם קיים קו שתחנתו הראשונה גדולה מתחנתו האחרונה של קו אחר‪.‬‬
‫מאפייני הבעיה‪ :‬מערך מונים‪ ,‬מקסימום‪ ,‬מינימום‪ ,‬מיזוג‪ ,‬מניה‪ ,‬שזירה של תבניות‪ ,‬מערך של עצמים‪.‬‬
‫פתרון‪:‬‬
/*
‫מחלקת קו אוטובוס‬
*/
class BusLine
{
// ‫משתני המחלקה‬
private String lineName;
// ‫מספר הקו‬
private int[] lineStations;
// ‫תחנות הקו‬
private int numOfStations;
// ‫פעולה בונה‬
public BusLine(String lineName, int[]lineStations)
{
this.lineName = lineName;
this.numOfStations = lineStations.length;
this.lineStations = new int[numOfStations];
for (int i=0; i< this.numOfStations; i++)
{
this.lineStations[i] = lineStations[i];
}
}
// ‫פעולות גישה‬
// ‫הפעולה מחזירה את מספר התחנות בקו‬
public int getNumberOfStations()
{
return this.numOfStations;
}
// ‫הפעולה מחזירה את התחנה המבוקשת בקו‬
public int getStationByNumber(int num)
{
return this.lineStations[num];
}
// ‫הפעולה מחזירה את התחנה הראשונה בקו‬
public int getFirstStation()
{
return this.lineStations[0];
}
//
‫הפעולה מחזירה את התחנה האחרונה בקו‬
public int getLastStation()
{
return this.lineStations[this.lineStations.length – 1];
}
// ‫אחרת‬
false-‫ אם התחנה שניתנה קיימת בקו ו‬true ‫הפעולה מחזירה‬
public boolean findStation(int stationNum)
{
int i;
for (i = 0; i < this.lineStations.length; i++)
{
if (this.lineStations[i] == stationNum)
{
return true;
}
} // for i
return false;
} // findStation
}// BusLine
/*
‫מחלקה ראשית‬
*/
public class Main
{
public static void main(String[] args)
{
//
‫הגדרת והקצאת משתנים‬
final int STATIONS_PER_LINE = 10;
// ‫ מספר תחנות לקו‬:‫קבוע‬
final int TOTAL_STATION_NUMBER = 100;
// ‫ מספר תחנות כולל‬:‫קבוע‬
int[] lineStations = new int[STATIONS_PER_LINE];
// ‫מערך קווים‬
BusLine[] busLine;
// ‫מערך קווי האוטוביס‬
int NumberOfLines;
// ‫קלט מספר קווים‬
int max = 0, maxStation = 0;
//
‫במקסימום קווים‬,
int line;
int station;
String lineName;
‫עבור מציאת מספר תחנה המופיע‬
int counter;
int maxFirst = 0; // ‫למציאת תחנה ראשונה מקסימלית‬
int minLast = TOTAL_STATION_NUMBER+1; // ‫למציאת תחנה אחרונה מינימלית‬
boolean foundMinMax = false; // ‫האם נמצא קו שתחנתו הראשונה גדולה‬
‫מתחנתו האחרונה של קו אחר‬
// ‫קלט מספר הקווים הקיים והקצאת המערך‬
NumberOfLines = InputRequestor.requestInt("Insert the number of
lines");
busLine = new BusLine[NumberOfLines];
// ‫קלט התחנות לכל קו‬
for (line = 0; line < NumberOfLines; line++)
{
lineName = InputRequestor.requestString("Insert the line name");
for (station=0; station < STATIONS_PER_LINE; station++)
{
lineStations[station] = InputRequestor.requestInt("Insert a
station number for line " + (int)(line+1));
} // for station
busLine[line] = new BusLine(lineName, lineStations);
} // for line
// ‫מציאת התחנה )הספרה( המשותפת למספר מירבי של אוטובוסים‬
for (station = 0; station <= TOTAL_STATION_NUMBER; station++)
{
counter = 0;
for (line = 0; line < NumberOfLines; line++)
{
if (busLine[line].findStation(station) == true)
{
counter++;
}
} // for line
if (counter > max)
{
max = counter;
maxStation = station+1;
//
‫ מכיוון‬1+ ‫נשמור את מספר התחנה‬
1 ‫שספירת התחנות מתחילה מ‬
}
} // for station
System.out.println("The common station is station number "+
maxStation );
// .2-‫ ו‬1 ‫מציאת מספר התחנות המשותפות לקווים‬
counter
= 0;
for (station = 0; station < busLine[0].getNumberOfStations();
station++)
{
if (busLine[1].findStation( busLine[0]. getStationByNumber(station)
)== true)
{
counter++;
}
} // for
System.out.println("The number of stations common to line 1 and line
2 is " + counter);
//.‫בדיקה האם יש קו שתחנתו הראשונה גדולה מתחנתו האחרונה של קו אחר‬
line = 0;
while (line < NumberOfLines && foundMinMax == false)
{
if (maxFirst < busLine[line].getFirstStation())
{ // ‫עדכון תחנה ראשונה מקסימלית עד כה‬
maxFirst = busLine[line].getFirstStation();
}
if (minLast > busLine[line].getLastStation())
{ // ‫עדכון תחנה אחרונה מינימלית עד כה‬
minLast = busLine[line].getLastStation();
}
if (minLast < maxFirst)
{
foundMinMax = true;
}
else
{
line++;
}
} // while
if (foundMinMax == true)
{
System.out.println("There is a line such that its first station is
bigger than other line last station");
}
else
{
System.out.println("There is NO line such that its first station is
bigger than other line last station");
}
}// main
} // class Main