דילוג לתוכן המרכזי

מתכונת 3 במדעי המחשב - יסודות מדעי המחשב 899371

1–2 יח"ל · שאלון 899371 · 6 שאלות · 2:30 שעות · פתרון מלא לכל סעיף

מבחן מתכונת במדעי המחשב, יסודות מדעי המחשב, במבנה של בחינת הבגרות. כל שאלה בו בנויה כמו שאלה מבגרות אחרת. לכל סעיף יש תשובה ופתרון מלא, וכל קוד מופיע ב-Java וב-C#. פתרו בזמן של הבחינה, ורק אחר כך פתחו את הפתרונות.

הוראות הבחינה

א. משך הבחינה: שעתיים וחצי.
ב. מבנה השאלון ומפתח ההערכה: בשאלון זה שני פרקים.
פרק ראשון – (20×2) – 40 נקודות
פרק שני – (30×2) – 60 נקודות
סך הכול – 100 נקודות
ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנוּת.
ד. הוראה מיוחדת:
את כל התוכניות שיש לכתוב בשפת מחשב כתבו בשפה אחת בלבד – Java או C#.
הערה: לא יוּרדוּ נקודות אם תכתבו בתוכניות אות גדולה במקום אות קטנה או להפך.

יש לכתוב במחברת הבחינה בלבד. יש לרשום "טיוטה" בראש כל עמוד המשמש טיוטה.
כתיבת טיוטה בדפים שאינם במחברת הבחינה עלולה לגרום לפסילת הבחינה.

השאלות בשאלון זה מנוסחות בלשון רבים, אף על פי כן על כל תלמידה וכל תלמיד להשיב עליהן באופן אישי.

בהצלחה!

השאלות
בשאלון זה שני פרקים.
יש לענות על שאלות משני הפרקים, לפי ההוראות בכל פרק.

הערה: בכל שאלה שנדרשת בה קליטה, אין צורך לבדוק את תקינות הקלט.
לפותרים בשפת Java: בכל שאלה שנדרשת בה קליטה, הניחו שבתוכנית כתובה ההוראה:
Scanner scan = new Scanner (System.in);

פרק ראשון (40 נקודות)

ענו על שתיים מן השאלות 1–3 (לכל שאלה – 20 נקודות).

שאלה 1 · מעקב – מציינים של שיאים חדשים במערך (20 נקודות)

נתונים שני מערכים מטיפוס שלם: a בגודל 8, ו־ b בגודל 7.

המערך a מכיל מספרים גדולים מ־ 0, והמערך b מכיל כולו אפסים.

01234567
a4772951212
0123456
b0000000

נתון קטע התכנית שלפניך, הכתוב ב־ Java וב־ C#.

Java

Java
int max = a[0];
int k = 0;
for(int i=1; i<a.length; i++)
{
      if(a[i] > max)
      {
         max = a[i];
         b[k] = i;
         k++;
      }
}

C#

C#
int max = a[0];
int k = 0;
for(int i=1; i<a.Length; i++)
{
      if(a[i] > max)
      {
         max = a[i];
         b[k] = i;
         k++;
      }
}
1.

עקבו בעזרת טבלת מעקב אחר ביצוע קטע התכנית בעבור המערכים a ו־ b הנתונים, ורישמו את המערך b לאחר ביצוע קטע התכנית.
בטבלת המעקב יש לכלול עמודה לכל אחד מהמשתנים האלה: b[k], k, max, a[i], i

2.

תנו דוגמה מייצגת למערך a בגודל 8 המכיל מספרים גדולים מ־ 0, שבעבורו, לאחר ביצוע קטע התכנית, בתא b[0] יהיה הערך 7, וכל שאר התאים במערך b יכילו 0.

◂ פתרון מלא לשאלה 1

סעיף 1

תשובה

b = {1, 4, 6, 0, 0, 0, 0} (k = 3, max = 12)

מה נדרש: לעקוב בטבלת מעקב אחר ביצוע הקטע על המערכים הנתונים, ולרשום את המערך b בסוף הביצוע.

רעיון: max שומר את הערך הגדול ביותר שנראה עד עכשיו (מתחיל ב־a[0]). הלולאה עוברת על a מתא 1 עד הסוף. בכל פעם שמופיע ערך גדול ממש מ־max ("שיא חדש"), max מתעדכן, והמציין i של השיא נכתב ל־b במקום k. שימו לב: ל־b נכתבים מציינים ולא ערכים, וערך ששווה לשיא הקודם אינו שיא חדש.

פתרון – טבלת מעקב (max, b[k] ו־k אחרי ביצוע גוף הלולאה):

ia[i]a[i] > max ?maxb[k]k
(התחלה)40
177 > 4 כן7b[0] ← 11
277 > 7 לא7–1
32לא7–1
499 > 7 כן9b[1] ← 42
55לא9–2
61212 > 9 כן12b[2] ← 63
71212 > 12 לא12–3
8הלולאה מסתיימת (8 < 8 לא מתקיים)123

המערך b לאחר ביצוע קטע התכנית:

0123456
b1460000

בדיקה: על המערכים הנתונים מתקבל b = 1 4 6 0 0 0 0, k = 3 ו־max = 12.

טעות נפוצה: לכתוב ל־b את הערכים 7, 9, 12 במקום המציינים 1, 4, 6, או לספור את 7 ואת 12 פעמיים – ההשוואה היא "גדול ממש", ולכן ערך שווה לשיא אינו נכתב.

סעיף 2

תשובה

למשל a = {5, 3, 5, 1, 4, 2, 5, 9} – כל מערך שבו a[1]…a[6] ≤ a[0] ו־a[7] > a[0].

מה נדרש: מערך a בגודל 8 עם מספרים גדולים מ־0, שבעבורו בסוף הביצוע b[0] = 7 וכל שאר תאי b הם 0.

רעיון: ל־b נכתבים מציינים i בין 1 ל־7, כלומר ערכים שונים מ־0. לכן:

•רק השמה אחת צריכה להתבצע (אחרת גם b[1] יהיה שונה מ־0),
•וההשמה הזאת צריכה לכתוב 7, כלומר השיא החדש היחיד יהיה בתא 7.

מכאן: a[1], …, a[6] לא גדולים מ־a[0] (אף אחד מהם אינו שיא חדש), ו־a[7] גדול ממש מ־a[0].

פתרון: דוגמה מייצגת:

01234567
a53514259

(גם 8, 8, 8, 8, 8, 8, 8, 20 מתאים: ערכים ששווים ל־a[0] אינם שיא חדש.)

בדיקה: בשתי הדוגמאות מתקבל b = 7 0 0 0 0 0 0 ו־k = 1. לעומת זאת, על 9, 1, 2, …, 7 (אין שיא חדש) התקבל b כולו אפסים, ועל 1, 2, …, 8 התקבל b = 1 2 3 4 5 6 7.

טעות נפוצה: לדרוש ש־a[0] יהיה הקטן ביותר. אז כמעט כל תא יהיה שיא חדש. צריך את ההפך: a[0] גדול או שווה לכל התאים שאחריו, חוץ מהאחרון.

שאלה 2 · לוח ההזמנות במטבח (20 נקודות)

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

כתבו פעולה בוליאנית חיצונית ששמה cancelOrder בשפת Java או CancelOrder בשפת C# , המקבלת את המערך orders ומספר הזמנה – num (מספר שלם חיובי).
אם ההזמנה num מופיעה במערך, הפעולה תמחק אותה כמתואר ותחזיר true . אחרת, המערך יישאר ללא שינוי ויוחזר false .

נתון המערך orders שלפניכם:

01234567
orders10411712198130000

דוגמה: עבור המערך orders ו־ num = 121 , הפעולה תחזיר true , והמערך ייראה כך בתום הפעולה:

01234567
orders104117981300000

הסבר: ההזמנה 121 נמצאה באינדקס 2 . ההזמנות 98 ו־ 130 (וגם התאים הריקים) זזו תא אחד שמאלה, והתא האחרון קיבל 0 .

דוגמה נוספת: עבור אותו המערך המקורי ו־ num = 200 , המערך יישאר ללא שינוי והפעולה תחזיר false , כי ההזמנה 200 אינה מופיעה בלוח.

כתבו פעולה בוליאנית חיצונית ששמה cancelOrder בשפת Java או CancelOrder בשפת C# , המקבלת את המערך orders ומספר הזמנה – num (מספר שלם חיובי).
אם ההזמנה num מופיעה במערך, הפעולה תמחק אותה כמתואר ותחזיר true . אחרת, המערך יישאר ללא שינוי ויוחזר false .

◂ פתרון מלא לשאלה 2

פתרון

תשובה

חיפוש סדרתי של num; כשנמצא באינדקס i – הזזה שמאלה orders[j] = orders[j+1] עבור j מ־ i עד length-2 , orders[length-1] = 0 , return true; אם לא נמצא – return false.

מה נדרש: למצוא את ההזמנה num ולמחוק אותה על ידי הזזה שמאלה של כל מה שאחריה; להחזיר אם ההזמנה נמצאה.

רעיון:

1.חיפוש סדרתי: עוברים על התאים עד שמוצאים את num .
2.כשנמצא באינדקס i – מזיזים שמאלה מ־ i קדימה: orders[j] = orders[j+1] עבור j מ־ i עד orders.length-2 . הערך שבתא i נדרס – וזו המחיקה.
3.התא האחרון נשאר עם עותק של הערך שהיה בו, ולכן מציבים בו 0 (לוח מלא הופך ללוח עם תא ריק אחד בסוף).
4.מחזירים true מיד. אם הלולאה הסתיימה בלי למצוא – מחזירים false , והמערך לא שונה.

פתרון:

public static boolean cancelOrder(int[] orders, int num)
{
    for (int i = 0; i < orders.length; i++)
    {
        if (orders[i] == num)
        {
            for (int j = i; j < orders.length - 1; j++)
            {
                orders[j] = orders[j + 1];
            }
            orders[orders.length - 1] = 0;
            return true;
        }
    }
    return false;
}

בדיקה:

•num = 121 → true , והמערך הפך ל־ 104 117 98 130 0 0 0 0 – כמו בדוגמה.
•num = 200 → false , והמערך נשאר 104 117 121 98 130 0 0 0 .
•num = 104 (בתא 0) → true , 117 121 98 130 0 0 0 0 .
•לוח מלא 5 6 7 8 9 10 11 12 : num = 12 (בתא האחרון) → 5 6 7 8 9 10 11 0 ; num = 5 → 6 7 8 9 10 11 12 0 .

טעות נפוצה: להזיז מהסוף להתחלה (for j = length-2 ... i) – כך הערך של התא האחרון מועתק לכל התאים מ־ i והלאה. בהזזה שמאלה חייבים להתחיל מתא i ולהתקדם. טעות נוספת: לשכוח לשים 0 בתא האחרון – בלוח מלא ההזמנה האחרונה תופיע אז פעמיים.

הקוד המלא
public static boolean cancelOrder(int[] orders, int num)
{
    for (int i = 0; i < orders.length; i++)
    {
        if (orders[i] == num)
        {
            for (int j = i; j < orders.length - 1; j++)
            {
                orders[j] = orders[j + 1];
            }
            orders[orders.length - 1] = 0;
            return true;
        }
    }
    return false;
}

שאלה 3 · מספר הר – ספרות עולות ואחר כך יורדות (20 נקודות)

מספר שלם חיובי – num ייקרא "מספר הר" אם יש בו לפחות 3 ספרות, וכאשר קוראים את ספרותיו משמאל לימין:

•הספרות עולות ממש (כל ספרה גדולה מזו שלפניה) עד ספרה אחת שנקראת "הפסגה", ומיד אחריה
•הספרות יורדות ממש (כל ספרה קטנה מזו שלפניה) עד הספרה האחרונה.

הפסגה אינה הספרה הראשונה במספר ואינה הספרה האחרונה בו.

דוגמאות ל"מספר הר":

•1352 – הספרות 1, 3, 5 עולות, והספרות 5, 2 יורדות (הפסגה היא 5).
•12321 – הספרות 1, 2, 3 עולות, והספרות 3, 2, 1 יורדות (הפסגה היא 3).
•120 – הספרות 1, 2 עולות, והספרות 2, 0 יורדות (הפסגה היא 2).

דוגמאות למספרים שאינם "מספר הר":

•1233 – יש שתי ספרות סמוכות שוות (3, 3).
•5310 – הספרות רק יורדות, אין עלייה.
•1357 – הספרות רק עולות, אין ירידה.
•1323 – אחרי הירידה מ־ 3 ל־ 2 יש שוב עלייה ל־ 3 .
א.

כתבו פעולה חיצונית ששמה isMountain בשפת Java או IsMountain בשפת C#, המקבלת מספר מטיפוס שלם – num הגדול מ־ 0 . הפעולה מחזירה true אם המספר הוא "מספר הר", אחרת היא מחזירה false .

ב.

כתבו פעולה חיצונית ששמה printMountains בשפת Java או PrintMountains בשפת C#, המקבלת מספר מטיפוס שלם – n הגדול מ־ 0 . הפעולה מדפיסה את כל "מספרי ההר" שיש מ־ 1 ועד n (כולל), ובסוף מדפיסה כמה "מספרי הר" נמצאו.
הערה: יש להשתמש בפעולה שכתבתם בסעיף א.

◂ פתרון מלא לשאלה 3

סעיף א

תשובה

עוברים על הספרות מימין לשמאל (‎% 10, / 10). מימין לשמאל "מספר הר" נראה כך: קודם ספרות שגדלות (צלע הירידה), ואחר כך ספרות שקטנות (צלע העלייה). שני דגלים up ו-down; ספרה שווה, קטנה לפני כל גדלה, או גדלה אחרי קטנה ← false; בסוף מחזירים up && down.

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

רעיון
את הספרות קל לקבל מימין לשמאל (בעזרת ‎% 10 ו-/ 10). קריאה מימין לשמאל של "מספר הר" נראית כך: קודם הספרות גדלות (זו צלע הירידה, הפוכה), ואחר כך הספרות קטנות (זו צלע העלייה, הפוכה).
שומרים את הספרה הקודמת prev ושני דגלים:

•up – ראינו ספרה גדולה מזו שמימינה (יש צלע ירידה).
•down – ראינו ספרה קטנה מזו שמימינה (יש צלע עלייה).

לכל ספרה d (משמאל ל-prev):

•d > prev: אם down כבר true – משמאל לימין יש כאן ירידה ואחריה שוב עלייה (יותר מפסגה אחת) ← false. אחרת up = true.
•d < prev: אם up עדיין false – אין צלע ירידה בצד ימין ← false. אחרת down = true.
•d == prev: ספרות שוות ← false.

בסוף המספר הוא "מספר הר" רק אם ראינו גם עלייה וגם ירידה: up && down. (מספר עם ספרה אחת או שתיים לא יכול לקבל את שני הדגלים, ולכן התנאי "לפחות 3 ספרות" מתקיים מעצמו.)

פתרון

Java

Java
public static boolean isMountain(int num)
{
    boolean up = false;     // ראינו ספרה גדולה מזו שמימינה (צלע הירידה של ההר)
    boolean down = false;   // ראינו ספרה קטנה מזו שמימינה (צלע העלייה של ההר)
    int prev = num % 10;    // הספרה הימנית ביותר
    num = num / 10;
    while (num > 0)
    {
        int d = num % 10;   // הספרה שמשמאל ל-prev
        if (d > prev)
        {
            if (down)
                return false;   // משמאל לימין: ירידה ואחריה שוב עלייה – יותר מפסגה אחת
            up = true;
        }
        else if (d < prev)
        {
            if (!up)
                return false;   // אין צלע ירידה בצד ימין
            down = true;
        }
        else
        {
            return false;       // שתי ספרות סמוכות שוות
        }
        prev = d;
        num = num / 10;
    }
    return up && down;
}

C#

C#
public static bool IsMountain(int num)
{
    bool up = false;        // ראינו ספרה גדולה מזו שמימינה (צלע הירידה של ההר)
    bool down = false;      // ראינו ספרה קטנה מזו שמימינה (צלע העלייה של ההר)
    int prev = num % 10;    // הספרה הימנית ביותר
    num = num / 10;
    while (num > 0)
    {
        int d = num % 10;   // הספרה שמשמאל ל-prev
        if (d > prev)
        {
            if (down)
                return false;   // משמאל לימין: ירידה ואחריה שוב עלייה – יותר מפסגה אחת
            up = true;
        }
        else if (d < prev)
        {
            if (!up)
                return false;   // אין צלע ירידה בצד ימין
            down = true;
        }
        else
        {
            return false;       // שתי ספרות סמוכות שוות
        }
        prev = d;
        num = num / 10;
    }
    return up && down;
}

בדיקה
מעקב על num = 1352:

dprevהשוואהupdown
(התחלה)2–falsefalse
52d > prevtruefalse
35d < prev, ‏up = truetruetrue
13d < prevtruetrue

בסוף up && down = true ✓

מעקב על num = 1323: ‏prev = 3, הספרה הבאה d = 2 < 3 אבל up עדיין false ← false ✓

1352, 12321, 120, 13531 ← true; ‏1233, 5310, 1357, 1323, 7, 98, 2552 ← false.

טעות נפוצה: לבדוק רק "יש עלייה ויש ירידה" בלי לוודא את הסדר – כך 1323 (עלייה, ירידה, עלייה) היה מתקבל בטעות. טעות נוספת: לשכוח את המקרה של ספרות שוות (1233).

הקוד המלא
public static boolean isMountain(int num)
{
    boolean up = false;     // ראינו ספרה גדולה מזו שמימינה (צלע הירידה של ההר)
    boolean down = false;   // ראינו ספרה קטנה מזו שמימינה (צלע העלייה של ההר)
    int prev = num % 10;    // הספרה הימנית ביותר
    num = num / 10;
    while (num > 0)
    {
        int d = num % 10;   // הספרה שמשמאל ל-prev
        if (d > prev)
        {
            if (down)
                return false;   // משמאל לימין: ירידה ואחריה שוב עלייה – יותר מפסגה אחת
            up = true;
        }
        else if (d < prev)
        {
            if (!up)
                return false;   // אין צלע ירידה בצד ימין
            down = true;
        }
        else
        {
            return false;       // שתי ספרות סמוכות שוות
        }
        prev = d;
        num = num / 10;
    }
    return up && down;
}

סעיף ב

תשובה

לולאה i = 1..n עם מונה count: אם isMountain(i) – מדפיסים i ומגדילים את count; אחרי הלולאה מדפיסים את count. למשל printMountains(140) מדפיסה 120, 121, 130, 131, 132, 140 ואחר כך את השורה count: 6.

מה נדרש
להדפיס את כל "מספרי ההר" מ-1 עד n, ובסוף את מספרם, תוך שימוש ב-isMountain מסעיף א.

רעיון
לולאה על i מ-1 עד n (כולל) עם מונה count שמתחיל ב-0. לכל i קוראים ל-isMountain(i); אם התשובה true – מדפיסים את i ומגדילים את count. אחרי הלולאה מדפיסים את count.

פתרון

Java

Java
public static void printMountains(int n)
{
    int count = 0;
    for (int i = 1; i <= n; i++)
    {
        if (isMountain(i))
        {
            System.out.println(i);
            count++;
        }
    }
    System.out.println("count: " + count);
}

C#

C#
public static void PrintMountains(int n)
{
    int count = 0;
    for (int i = 1; i <= n; i++)
    {
        if (IsMountain(i))
        {
            Console.WriteLine(i);
            count++;
        }
    }
    Console.WriteLine("count: " + count);
}

בדיקה
printMountains(140) מדפיסה (כל מספר בשורה נפרדת):
120, 121, 130, 131, 132, 140 ואחריהם count: 6.
(למשל 122 אינו "מספר הר" – הספרות 2, 2 שוות; ‏123 אינו – אין ירידה.) התוצאה זהה לבדיקה עצמאית שכתבנו בנפרד, וגם הספירה עד 99999 (‏6198 מספרים) זהה.

טעות נפוצה: להדפיס את count בתוך הלולאה – כך הוא מודפס שוב ושוב במקום פעם אחת בסוף.

הקוד המלא
public static void printMountains(int n)
{
    int count = 0;
    for (int i = 1; i <= n; i++)
    {
        if (isMountain(i))
        {
            System.out.println(i);
            count++;
        }
    }
    System.out.println("count: " + count);
}

פרק שני (60 נקודות)

ענו על שתיים מן השאלות 4–6 (לכל שאלה – 30 נקודות).

שאלה 4 · סיורים במוזיאון – Tour ומערך של סיורים (30 נקודות)

מוזיאון הטבע מציע לקבוצות מבקרים סיורים מודרכים. כל סיור מתקיים בעברית או באנגלית.

נתונה המחלקה Tour – סיור, ולה ארבע תכונות:

•guide – שם המדריך של הסיור, מטיפוס מחרוזת
•hebrew – שפת הסיור. בעבור סיור בעברית ערך התכונה הוא true , ובעבור סיור באנגלית הערך הוא false .
•visitors – מספר המבקרים בסיור – מספר מטיפוס שלם בין 1 ל־ 25 (כולל)
•month – מספר מטיפוס שלם בין 1 ל־ 12 (כולל), המייצג את החודש שבו התקיים הסיור (ינואר–דצמבר בהתאמה)

הניחו שקיימות פעולות get/Get לתכונות המחלקה.

א.(1)

כתבו פעולה בונה במחלקה Tour , המקבלת את שם המדריך – guide , את מספר המבקרים – visitors , ואת החודש – month .
הפעולה תאתחל את תכונות המחלקה. בשפת הסיור (hebrew) הפעולה תיצור סיור בעברית.
הניחו שהפרמטרים שמתקבלים תקינים.

(2)

כתבו פעולה בונה במחלקה Tour המקבלת רק את החודש – month .
הפעולה תאתחל את תכונות המחלקה כך שיתקבל סיור באנגלית בהדרכת Maya , בחודש month , עם קבוצה מלאה של 25 מבקרים.
הערה: אם הפרמטר month אינו תקין, התכונה תקבל 7 (חודש יולי).

ב.(1)

נתון מערך – arr , מטיפוס Tour , המכיל את כל הסיורים שהתקיימו במוזיאון במהלך שנה אחת. המערך אינו ממוין לפי סדר כלשהו, ואין בו ערכי null .

כתבו פעולה חיצונית ששמה avgVisitors בשפת Java או AvgVisitors בשפת C#, המקבלת את המערך arr , מספר מטיפוס שלם – month המציין חודש, ופרמטר בוליאני – hebrew .
אם hebrew הוא true , הפעולה תחזיר את ממוצע מספר המבקרים בסיור, מבין הסיורים בעברית שהתקיימו בחודש month .
אחרת (אם hebrew הוא false ), הפעולה תחזיר את ממוצע מספר המבקרים בסיור, מבין הסיורים באנגלית שהתקיימו בחודש month .
אם לא התקיים אף סיור מתאים, הפעולה תחזיר 0 .
הממוצע הוא מספר ממשי (double), ויכול להיות לא שלם.
הניחו שהפרמטר month שמתקבל תקין (בין 1 ל־ 12 ).

(2)

כתבו פעולה חיצונית ששמה onlyHebrew בשפת Java או OnlyHebrew בשפת C#, המקבלת את המערך arr .
הפעולה תדפיס את מספרי החודשים שבהם התקיים לפחות סיור אחד בעברית, ולא התקיים אף סיור באנגלית.
הערה: אפשר להיעזר בפעולה שכתבתם בתת־סעיף ב(1).

◂ פתרון מלא לשאלה 4

סעיף א(1)

תשובה

this.guide = guide; this.visitors = visitors; this.month = month; this.hebrew = true;

מה נדרש
פעולה בונה עם שלושה פרמטרים שמאתחלת את ארבע התכונות; hebrew מקבלת תמיד true (סיור בעברית).

רעיון
מציבים כל פרמטר בתכונה המתאימה. התכונה hebrew אינה פרמטר – מציבים בה true. אין צורך לבדוק תקינות.

פתרון
כותרת המחלקה והתכונות:

Java

Java
public class Tour
{
    private String guide;      // שם המדריך
    private boolean hebrew;    // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

C#

C#
public class Tour
{
    private string guide;      // שם המדריך
    private bool hebrew;       // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

הפעולה הבונה:

Java

Java
    // סעיף א(1)
    public Tour(String guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

C#

C#
    // סעיף א(1)
    public Tour(string guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

המחלקה המלאה – בלשונית הקוד.

בדיקה
new Tour("Eli", 18, 3) ← guide = "Eli", hebrew = true, visitors = 18, month = 3.

הקוד המלא
public class Tour
{
    private String guide;      // שם המדריך
    private boolean hebrew;    // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

    // סעיף א(1)
    public Tour(String guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

    // פעולה בונה מלאה – לצורך הבדיקה בלבד
    public Tour(String guide, boolean hebrew, int visitors, int month)
    {
        this.guide = guide;
        this.hebrew = hebrew;
        this.visitors = visitors;
        this.month = month;
    }

    public String getGuide() { return this.guide; }
    public boolean getHebrew() { return this.hebrew; }
    public int getVisitors() { return this.visitors; }
    public int getMonth() { return this.month; }
}

סעיף א(2)

תשובה

guide = "Maya", hebrew = false, visitors = 25, month = (1 ≤ month ≤ 12 ? month : 7).

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

רעיון

•guide = "Maya"
•hebrew = false (סיור באנגלית)
•visitors = 25
•month: אם 1 ≤ month ≤ 12 מציבים את month, אחרת 7.

פתרון
Java

Java
    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

C#

C#
    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

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

Java

Java
public class Tour
{
    private String guide;      // שם המדריך
    private boolean hebrew;    // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

    // סעיף א(1)
    public Tour(String guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

    // פעולה בונה מלאה – לצורך הבדיקה בלבד
    public Tour(String guide, boolean hebrew, int visitors, int month)
    {
        this.guide = guide;
        this.hebrew = hebrew;
        this.visitors = visitors;
        this.month = month;
    }

    public String getGuide() { return this.guide; }
    public boolean getHebrew() { return this.hebrew; }
    public int getVisitors() { return this.visitors; }
    public int getMonth() { return this.month; }
}

C#

C#
public class Tour
{
    private string guide;      // שם המדריך
    private bool hebrew;       // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

    // סעיף א(1)
    public Tour(string guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

    // פעולה בונה מלאה – לצורך הבדיקה בלבד
    public Tour(string guide, bool hebrew, int visitors, int month)
    {
        this.guide = guide;
        this.hebrew = hebrew;
        this.visitors = visitors;
        this.month = month;
    }

    public string GetGuide() { return this.guide; }
    public bool GetHebrew() { return this.hebrew; }
    public int GetVisitors() { return this.visitors; }
    public int GetMonth() { return this.month; }
}

בדיקה

•new Tour(11) ← "Maya", false, 25, 11 ✓
•new Tour(0) ← month = 7 ✓ ; new Tour(13) ← month = 7 ✓ ; new Tour(12) ← month = 12 ✓

טעות נפוצה: להציב 7 תמיד, או להציב את month בלי בדיקה. לפי ההערה, 7 מוצב רק כשהערך שהתקבל אינו בין 1 ל-12.

הקוד המלא
public class Tour
{
    private String guide;      // שם המדריך
    private boolean hebrew;    // true = סיור בעברית, false = סיור באנגלית
    private int visitors;      // מספר המבקרים בסיור (1–25)
    private int month;         // החודש שבו התקיים הסיור (1–12)

    // סעיף א(1)
    public Tour(String guide, int visitors, int month)
    {
        this.guide = guide;
        this.visitors = visitors;
        this.month = month;
        this.hebrew = true;        // סיור בעברית
    }

    // סעיף א(2)
    public Tour(int month)
    {
        this.guide = "Maya";
        this.hebrew = false;       // סיור באנגלית
        this.visitors = 25;        // קבוצה מלאה
        if (month >= 1 && month <= 12)
            this.month = month;
        else
            this.month = 7;        // יולי
    }

    // פעולה בונה מלאה – לצורך הבדיקה בלבד
    public Tour(String guide, boolean hebrew, int visitors, int month)
    {
        this.guide = guide;
        this.hebrew = hebrew;
        this.visitors = visitors;
        this.month = month;
    }

    public String getGuide() { return this.guide; }
    public boolean getHebrew() { return this.hebrew; }
    public int getVisitors() { return this.visitors; }
    public int getMonth() { return this.month; }
}

סעיף ב(1)

תשובה

סוכמים ומונים את הסיורים שבהם getMonth() == month וגם getHebrew() == hebrew; מחזירים (double) sum / count, או 0 אם count == 0.

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

רעיון
סריקה של המערך עם שני צוברים: sum (סך המבקרים) ו-count (מספר הסיורים המתאימים). סיור מתאים אם getMonth() == month וגם getHebrew() == hebrew. בסוף: אם count == 0 מחזירים 0 (כדי לא לחלק באפס), אחרת מחזירים sum / count – עם המרה ל-double כדי שהחלוקה לא תהיה חלוקת שלמים.

פתרון
Java

Java
// סעיף ב(1)
public static double avgVisitors(Tour[] arr, int month, boolean hebrew)
{
    int sum = 0;
    int count = 0;
    for (int i = 0; i < arr.length; i++)
    {
        if (arr[i].getMonth() == month && arr[i].getHebrew() == hebrew)
        {
            sum = sum + arr[i].getVisitors();
            count++;
        }
    }
    if (count == 0)
    {
        return 0;
    }
    return (double) sum / count;
}

C#

C#
// סעיף ב(1)
public static double AvgVisitors(Tour[] arr, int month, bool hebrew)
{
    int sum = 0;
    int count = 0;
    for (int i = 0; i < arr.Length; i++)
    {
        if (arr[i].GetMonth() == month && arr[i].GetHebrew() == hebrew)
        {
            sum = sum + arr[i].GetVisitors();
            count++;
        }
    }
    if (count == 0)
    {
        return 0;
    }
    return (double) sum / count;
}

בדיקה
מערך בדיקה (מדריך, שפה, מבקרים, חודש): (Eli, עברית, 20, 1), (Dana, עברית, 15, 1), new Tour(1), (Eli, עברית, 12, 2), (Dana, עברית, 9, 2), (Eli, עברית, 10, 3), (Dana, אנגלית, 6, 3), (Eli, אנגלית, 9, 3), new Tour(4), (Dana, עברית, 25, 8), new Tour(50).
(new Tour(m) הוא סיור באנגלית עם 25 מבקרים; new Tour(50) מתקיים בחודש 7.)

•avgVisitors(arr, 1, true) = (20 + 15) / 2 = 17.5
•avgVisitors(arr, 2, true) = (12 + 9) / 2 = 10.5
•avgVisitors(arr, 2, false) = 0 (אין סיורים באנגלית בפברואר)
•avgVisitors(arr, 3, false) = (6 + 9) / 2 = 7.5
•avgVisitors(arr, 7, false) = 25

טעות נפוצה: לכתוב sum / count בלי המרה – בחלוקת שלמים (12 + 9) / 2 נותן 10 ולא 10.5. וגם לשכוח את המקרה count == 0, שגורם לחלוקה באפס.

הקוד המלא
// סעיף ב(1)
public static double avgVisitors(Tour[] arr, int month, boolean hebrew)
{
    int sum = 0;
    int count = 0;
    for (int i = 0; i < arr.length; i++)
    {
        if (arr[i].getMonth() == month && arr[i].getHebrew() == hebrew)
        {
            sum = sum + arr[i].getVisitors();
            count++;
        }
    }
    if (count == 0)
    {
        return 0;
    }
    return (double) sum / count;
}

סעיף ב(2)

תשובה

לכל m מ-1 עד 12: אם avgVisitors(arr, m, true) > 0 וגם avgVisitors(arr, m, false) == 0 – מדפיסים את m.

מה נדרש
להדפיס כל חודש שבו היו סיורים בעברית בלבד (לפחות אחד), ואף לא סיור אחד באנגלית.

רעיון
בכל סיור יש לפחות מבקר אחד (visitors ≥ 1), ולכן הממוצע מסעיף ב(1) גדול מ-0 אם ורק אם התקיים לפחות סיור אחד מתאים, והוא שווה 0 בדיוק כשאין סיור כזה. לכן עוברים על החודשים 1–12 ובודקים: ממוצע בעברית > 0 וגם ממוצע באנגלית == 0.

פתרון
Java

Java
// סעיף ב(2)
public static void onlyHebrew(Tour[] arr)
{
    for (int m = 1; m <= 12; m++)
    {
        if (avgVisitors(arr, m, true) > 0 && avgVisitors(arr, m, false) == 0)
        {
            System.out.println(m);
        }
    }
}

C#

C#
// סעיף ב(2)
public static void OnlyHebrew(Tour[] arr)
{
    for (int m = 1; m <= 12; m++)
    {
        if (AvgVisitors(arr, m, true) > 0 && AvgVisitors(arr, m, false) == 0)
        {
            Console.WriteLine(m);
        }
    }
}

בדיקה
על מערך הבדיקה מסעיף ב(1):

•חודש 1: יש עברית ויש אנגלית ← לא מודפס
•חודש 2: עברית 10.5, אנגלית 0 ← מודפס
•חודש 3: יש שתי השפות ← לא מודפס
•חודש 4: אנגלית בלבד ← לא מודפס
•חודש 7: אנגלית בלבד ← לא מודפס
•חודש 8: עברית 25, אנגלית 0 ← מודפס

הפלט: 2, 8 – כל אחד בשורה נפרדת.

טעות נפוצה: לבדוק רק שהממוצע באנגלית הוא 0 – אז יודפסו גם חודשים שלא התקיים בהם שום סיור (למשל חודש 5).

הקוד המלא
// סעיף ב(2)
public static void onlyHebrew(Tour[] arr)
{
    for (int m = 1; m <= 12; m++)
    {
        if (avgVisitors(arr, m, true) > 0 && avgVisitors(arr, m, false) == 0)
        {
            System.out.println(m);
        }
    }
}

שאלה 5 · רכבות ושעות יציאה – מחלקה מורכבת (30 נקודות)

נתונה המחלקה Time – שעה ביום, ולה שתי תכונות:

•hour – השעה (מספר בין 0 ל־ 23), מטיפוס שלם
•minute – הדקה (מספר בין 0 ל־ 59), מטיפוס שלם

הניחו שקיימות פעולות get/Get ו־ set/Set לתכונות המחלקה.
בשאלה זו כל השעות הן באותו יום.

א.

כתבו במחלקה Time פעולה פנימית ששמה minutesBetween בשפת Java או MinutesBetween בשפת C# המקבלת עצם אחר – other מטיפוס Time .
הפעולה מחזירה את מספר הדקות שבין שתי השעות (מספר שאינו שלילי, בלי קשר לשאלה איזו מן השעות מוקדמת יותר).
למשל, בין 8:55 ל־ 9:02 יש 7 דקות.

ב.(1)

בתחנת רכבת מרכזית פיתחו מערכת שבודקת את לוח הזמנים של הרכבות היוצאות מן התחנה. לשם כך נבנתה המחלקה Train – רכבת, ולה שלוש תכונות:

•line – האות המזהה את קו הרכבת (אות גדולה באנגלית), מטיפוס char
•platform – מספר הרציף שממנו יוצאת הרכבת, מטיפוס שלם
•departure – שעת היציאה של הרכבת, מטיפוס Time

הניחו שקיימות פעולות get/Get ו־ set/Set לתכונות המחלקה.

כתבו במחלקה Train פעולה פנימית ששמה samePlatform בשפת Java או SamePlatform בשפת C# , המקבלת עצם אחר – other מטיפוס Train . הפעולה מחזירה true אם שתי הרכבות יוצאות מאותו רציף. אחרת הפעולה מחזירה false .

(2)

במערכת זו, שתי רכבות נמצאות "בהתנגשות" אם גם הן יוצאות מאותו רציף וגם ההפרש בין שעות היציאה שלהן קטן מ־ 4 דקות (אם רק תנאי אחד מתקיים, הרכבות אינן בהתנגשות).
כתבו במחלקה Train פעולה פנימית ששמה tooClose בשפת Java או TooClose בשפת C# , המקבלת עצם אחר – other מטיפוס Train . הפעולה מחזירה true אם שתי הרכבות נמצאות "בהתנגשות", אחרת הפעולה מחזירה false .
יש להשתמש בפעולות שכתבתם בסעיף א ובתת־סעיף ב(1).

ג.

כתבו פעולה חיצונית ששמה countConflicts בשפת Java או CountConflicts בשפת C# המקבלת מערך – trains מטיפוס Train של כל הרכבות היוצאות מן התחנה ביום מסוים. המערך אינו מסודר לפי סדר כלשהו ואין בו ערכי null . הפעולה תחזיר את מספר הזוגות של רכבות שנמצאות "בהתנגשות" (כל זוג נספר פעם אחת בלבד).
למשל, אם במערך יש שלוש רכבות בלבד, וכולן יוצאות מרציף 1 בשעות 7:00 , 7:02 ו־ 7:05 – הפעולה תחזיר 2 (הזוג של 7:00 ו־ 7:02 והזוג של 7:02 ו־ 7:05; בין 7:00 ל־ 7:05 יש 5 דקות).
יש להשתמש בפעולה שכתבתם בתת־סעיף ב(2).

◂ פתרון מלא לשאלה 5

סעיף א

תשובה

return Math.abs((hour * 60 + minute) - (other.getHour() * 60 + other.getMinute()));

מה נדרש: פעולה פנימית ב־ Time המחזירה את ההפרש בדקות בין שתי שעות.

רעיון: ממירים כל שעה למספר הדקות מתחילת היום: hour * 60 + minute. ההפרש בין שני המספרים הוא ההפרש בדקות, ו־ Math.abs (ב־ C#: Math.Abs) הופך אותו לאי־שלילי. את התכונות של other קוראים בפעולות get.

פתרון: הקוד המלא – בלשונית Java / C#.

בדיקה: 8:55 מול 9:02 → 7 (535 ו־ 542 דקות); 9:02 מול 8:55 → 7; 14:30 מול 14:30 → 0; 0:00 מול 23:59 → 1439.

טעות נפוצה: לחסר בנפרד שעות ודקות: (9 − 8) ו־ (2 − 55) – ההפרש בדקות יוצא שלילי ומבלבל. ההמרה לדקות פותרת זאת.

הקוד המלא
public int minutesBetween(Time other)
{
    int mine = this.hour * 60 + this.minute;
    int his = other.getHour() * 60 + other.getMinute();
    return Math.abs(mine - his);
}

סעיף ב(1)

תשובה

return platform == other.getPlatform();

מה נדרש: פעולה פנימית ב־ Train הבודקת אם שתי רכבות יוצאות מאותו רציף.

רעיון: platform הוא מספר שלם, ולכן משווים אותו ישירות עם == ל־ other.getPlatform().

פתרון: הקוד המלא – בלשונית Java / C#.

בדיקה: רציף 2 מול רציף 2 → true; רציף 2 מול רציף 3 → false.

הקוד המלא
public boolean samePlatform(Train other)
{
    return this.platform == other.getPlatform();
}

סעיף ב(2)

תשובה

return samePlatform(other) && departure.minutesBetween(other.getDeparture()) < 4;

מה נדרש: פעולה tooClose המחזירה true רק אם הרכבות יוצאות מאותו רציף וגם ההפרש בין שעות היציאה קטן מ־ 4 דקות.

רעיון: זו מחלקה מורכבת – התכונה departure היא עצם מטיפוס Time. לכן את חישוב ההפרש מעבירים לפעולה minutesBetween של העצם departure:
this.departure.minutesBetween(other.getDeparture()), ומחברים עם samePlatform(other) ב־ &&.

פתרון: הקוד המלא – בלשונית Java / C#.

בדיקה: רציף 2, 8:58 מול רציף 2, 9:01 (3 דקות) → true; רציף 2, 8:58 מול רציף 2, 9:02 (4 דקות) → false (4 אינו קטן מ־ 4); רציף 2 מול רציף 3 באותה שעה → false.

טעות נפוצה: לכתוב ≤ 4 במקום < 4 – "קטן מ־ 4 דקות" אינו כולל הפרש של 4 דקות בדיוק.

הקוד המלא
public boolean tooClose(Train other)
{
    return this.samePlatform(other) &&
           this.departure.minutesBetween(other.getDeparture()) < 4;
}

סעיף ג

תשובה

לולאה כפולה i < j: אם trains[i].tooClose(trains[j]) – count++; מחזירים count

מה נדרש: לספור את כל הזוגות השונים של רכבות שנמצאות בהתנגשות.

רעיון: לולאה כפולה על כל הזוגות: i מ־ 0, ו־ j מ־ i + 1. כך כל זוג {i, j} נבדק פעם אחת בדיוק, ורכבת אינה מושווית לעצמה. לכל זוג שבו trains[i].tooClose(trains[j]) מגדילים מונה.
(ההתנגשות סימטרית – אם i מתנגשת ב־ j גם j מתנגשת ב־ i – ולכן אין צורך לבדוק את הזוג בשני הכיוונים.)

פתרון: הקוד המלא – בלשונית Java / C#.

בדיקה: הדוגמה מהשאלה → 2. מערך של 6 רכבות: A רציף 1 7:00, B רציף 1 7:02, C רציף 1 7:05, D רציף 2 7:03, E רציף 2 8:00, F רציף 1 7:03. הזוגות בהתנגשות: A–B (2 דק'), A–F (3), B–C (3), B–F (1), C–F (2) → הוחזר 5. מערך בלי התנגשויות → 0.

טעות נפוצה: להריץ את j מ־ 0 עם התנאי i != j – כך כל זוג נספר פעמיים (התוצאה בדוגמה תהיה 4 במקום 2).

הקוד המלא
public static int countConflicts(Train[] trains)
{
    int count = 0;
    for (int i = 0; i < trains.length; i++)
    {
        for (int j = i + 1; j < trains.length; j++)
        {
            if (trains[i].tooClose(trains[j]))
                count++;
        }
    }
    return count;
}

שאלה 6 · כיווץ מסר ושחזורו

כדי לחסוך מקום, אפליקציית מסרים מסוימת "מכווצת" כל מסר: כל רצף של תווים זהים הסמוכים זה לזה מוחלף בתו אחד בלבד.
לדוגמה: לאחר כיווץ המילה bookkeeper מתקבל המסר המכווץ bokeper .

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

0123456
1222111

הסבר: התו הראשון במסר המכווץ (b) הופיע במסר המקורי פעם אחת, התו השני במסר המכווץ (o) הופיע במסר המקורי פעמיים ברצף, התו השלישי במסר המכווץ (k) הופיע במסר המקורי פעמיים ברצף, וכן הלאה.

א.

רשמו את המסר המכווץ ואת מערך המונים עבור המסר Mississippi .

ב.

כתבו פעולה חיצונית ששמה expand בשפת Java או Expand בשפת C# , המקבלת מחרוזת מכווצת – str ומערך מונים – arr . הפעולה תחזיר את המחרוזת המקורית.

◂ פתרון מלא לשאלה 6

סעיף א

תשובה

המסר המכווץ: Misisipi ; מערך המונים: {1, 1, 2, 1, 2, 1, 2, 1}

מה נדרש: לכווץ את Mississippi ולרשום את מערך המונים.

רעיון: מחלקים את המסר לרצפים של תווים זהים סמוכים: M | i | ss | i | ss | i | pp | i. מכל רצף נשאר תו אחד, והמונה הוא אורך הרצף. (שימו לב: M גדולה ו־i קטנה – תווים שונים.)

פתרון: המסר המכווץ הוא Misisipi (8 תווים), ומערך המונים:

01234567
11212121

בדיקה: סכום המונים 1+1+2+1+2+1+2+1 = 11 = אורך Mississippi. בתוכנית הבדיקה כיווצנו את Mississippi וקיבלנו Misisipi / 1 1 2 1 2 1 2 1, והפעולה מסעיף ב שחזרה ממנו את Mississippi.

טעות נפוצה: לספור את כל המופעים של תו במילה (למשל s מופיעה 4 פעמים) במקום את אורך הרצף; או למזג את כל ה־i למונה אחד – כל רצף נפרד מקבל תא משלו.

סעיף ב

תשובה

לכל i משרשרים לתוצאה את str.charAt(i) בדיוק arr[i] פעמים (לולאה מקוננת).

מה נדרש: לבנות את המסר המקורי מהמסר המכווץ ומערך המונים.

רעיון: התו ה־i במסר המכווץ הופיע במקור arr[i] פעמים ברצף, ולפי הסדר. לכן עוברים על התווים לפי הסדר, ולכל תו מוסיפים אותו לתוצאה arr[i] פעמים בלולאה פנימית.

פתרון: הקוד המלא – בלשונית Java/C#.

בדיקה:

•expand("bokeper", {1,2,2,2,1,1,1}) → bookkeeper (הדוגמה שבשאלה).
•expand("Misisipi", {1,1,2,1,2,1,2,1}) → Mississippi (סעיף א).
•expand("a", {5}) → aaaaa; expand("xyx", {1,3,1}) → xyyyx.

טעות נפוצה: לכתוב result += str.charAt(i) * arr[i] – כפל של תו במספר נותן מספר ולא חזרה על התו; או לכתוב result += arr[i] ולשרשר את המספר עצמו.

הקוד המלא
public class Q6
{
    public static String expand(String str, int[] arr)
    {
        String result = "";
        for (int i = 0; i < str.length(); i++)
        {
            for (int k = 0; k < arr[i]; k++)    // התו ה־i חוזר arr[i] פעמים
                result += str.charAt(i);
        }
        return result;
    }
}
טבלת התשובות
שאלהסעיףתשובה
11

b = {1, 4, 6, 0, 0, 0, 0} (k = 3, max = 12)

2

למשל a = {5, 3, 5, 1, 4, 2, 5, 9} – כל מערך שבו a[1]…a[6] ≤ a[0] ו־a[7] > a[0].

2-

חיפוש סדרתי של num; כשנמצא באינדקס i – הזזה שמאלה orders[j] = orders[j+1] עבור j מ־ i עד length-2 , orders[length-1] = 0 , return true; אם לא נמצא – return false.

3א

עוברים על הספרות מימין לשמאל (‎% 10, / 10). מימין לשמאל "מספר הר" נראה כך: קודם ספרות שגדלות (צלע הירידה), ואחר כך ספרות שקטנות (צלע העלייה). שני דגלים up ו-down; ספרה שווה, קטנה לפני כל גדלה, או גדלה אחרי קטנה ← false; בסוף מחזירים up && down.

ב

לולאה i = 1..n עם מונה count: אם isMountain(i) – מדפיסים i ומגדילים את count; אחרי הלולאה מדפיסים את count. למשל printMountains(140) מדפיסה 120, 121, 130, 131, 132, 140 ואחר כך את השורה count: 6.

4א(1)

this.guide = guide; this.visitors = visitors; this.month = month; this.hebrew = true;

א(2)

guide = "Maya", hebrew = false, visitors = 25, month = (1 ≤ month ≤ 12 ? month : 7).

ב(1)

סוכמים ומונים את הסיורים שבהם getMonth() == month וגם getHebrew() == hebrew; מחזירים (double) sum / count, או 0 אם count == 0.

ב(2)

לכל m מ-1 עד 12: אם avgVisitors(arr, m, true) > 0 וגם avgVisitors(arr, m, false) == 0 – מדפיסים את m.

5א

return Math.abs((hour * 60 + minute) - (other.getHour() * 60 + other.getMinute()));

ב(1)

return platform == other.getPlatform();

ב(2)

return samePlatform(other) && departure.minutesBetween(other.getDeparture()) < 4;

ג

לולאה כפולה i < j: אם trains[i].tooClose(trains[j]) – count++; מחזירים count

6א

המסר המכווץ: Misisipi ; מערך המונים: {1, 1, 2, 1, 2, 1, 2, 1}

ב

לכל i משרשרים לתוצאה את str.charAt(i) בדיוק arr[i] פעמים (לולאה מקוננת).

כל האתר במבט אחד

קיצורי דרך לכל הכלים, הבגרויות והקורסים

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