6. מערכים דו-ממדיים

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

מוטיבציה

6.pdf

6.1 דוגמות ראשונות - קריאת נתונים למערך בשיטות שונות

הסבר כתוב אודות: דוגמות ראשונות - קריאת נתונים למערך בשיטות שונות

6.1.pdf

תרגול עצמי בסיסי בנושא: דוגמות ראשונות לשימוש במערך דו-ממדי

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

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

לבסוף התכנית מציגה את תוכנו של המערך

דוגמות בסיסיות נוספות בנושא מערך דו-ממדי

איתור הקורס בו ממוצע הציונים מזערי


איתור הסטודנט המצטיין בכיתה


הסבר כתוב אודות ספירת מספר הקורסים בהם תלמיד נכשל, ואודות מציאת הקורס בו ממוצע הציונים הוא מרבי

6.1b.pdf

תרגול עצמי בסיסי נוסף בנושא מערכים דו-ממדיים

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

עתה התכנית מציגה לכל שורה ושורה במערך את ממוצע הערכים בשורה.

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

6.2 בדיקה האם מערך דו-ממדי הינו ריבוע קסם

הסבר כתוב אודות: בדיקה האם מערך דו-ממדי הינו ריבוע קסם

6.2.pdf

תרגול עצמי בסיסי נוסף בנושא מערכים דו-ממדיים

כתבו תכנית המגדירה מערך דו-ממדי בן ארבע שורות וארבע עמודות, וקוראת לתוכו נתונים.

עתה התכנית תציג את:

  • סכום הערכים בתאי האלכסון הראשי
  • סכום הערכים בתאים שמעל האלכסון הראשי
  • סכום הערכים בתאים שמתחת לאלכסון הראשי

6.3 בדיקה האם מערך דו-ממדי 'קטן' משוכן במערך דו-ממדי 'גדול'

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

הסבר כתוב אודות: בדיקה האם מערך דו-ממדי 'קטן' משוכן במערך דו-ממדי 'גדול'

6.3.pdf

תרגול עצמי 'בסיסי' בנושא מערכים דו-ממדיים

תרגיל זה כבר אינו כל כך בסיסי.

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

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

6.4 משחק איקס-עיגול נגד המחשב

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

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

// --------------------- include section ----------------------------

#include <iostream>

#include <cstdlib>

#include <ctime>

// --------------------- using section ----------------------------

using std::cin ;

using std::cout ;

using std::endl ;

// --------------------- const section ----------------------------

const int N = 3 , // board size

EMPTY = 0, // values borad[][] may hold

COMP = 1,

USER = -1 ;

// --------------------- main ----------------------------

int main()

{

int board[N][N] , // the game board

row, col, // current move

temp_row, temp_col, // for printing the board

round, // round in game

i ; // index for loops

bool win ; // did somebody win

srand(time(NULL)) ; // initialize the random number gen.

// init the board to be empty

for (row = 0; row < N; row++)

for (col = 0; col < N; col++)

board[row][col] = EMPTY ;

// run the game (at most N*N rounds)

for (round = 0; round < N*N; round++)

{

// get the next move

do

{

if (round % 2 == 0) // user's turn

cin >> row >> col ;

else // computer turn

{

row = rand() % N ; // is picked by random

col = rand() % N ;

}

} while (row < 0 || row >= N ||

col < 0 || col >= N ||

board[row][col] != EMPTY ) ;

// mark the board

board[row][col] = (round % 2 == 0) ? USER : COMP ;

// draw current board

cout << endl << "Board after round #" << round << endl ;

for (temp_row = 0; temp_row < N; temp_row++)

{

for (temp_col = 0; temp_col < N; temp_col++)

if (board[temp_row][temp_col] == EMPTY)

cout << " - " ;

else if (board[temp_row][temp_col] == USER)

cout << " X " ;

else cout << " O " ;

cout << endl ;

}

// check if there is a winner

win = true ; // did someone win by completing line

for (i = 0; i < N && win; i++)

if (board[row][i] != board[row][col])

win = false ;

if (win)

break ;

win = true ; // win by completing a column

for (i = 0; i < N && win; i++)

if (board[i][col] != board[row][col])

win = false ;

if (win)

break ;

win = true ; //win by completing main diagonal

for (i = 1; i < N && win; i++)

if (board[i][i] != board[0][0] || board[i][i] == EMPTY)

win = false ;

if (win)

break ;

win = true ; // win by completing secondary diagonal

for (i = 1; i < N && win; i++)

if (board[i][N-1-i] != board[0][N-1] ||

board[i][N-1-i] == EMPTY)

win = false ;

if (win)

break ;

}

if (win) // if someone win

if (round % 2 == 0) // if it is in even round

cout << "You won\n" ; // it must be the user

else

cout << "Sorry, I won\n" ;

else

cout << "Tie\n" ;

return EXIT_SUCCESS ;

}

6.5 טיפוסים ברי מניה, משתנים מטיפוס enum

הסבר כתוב אודות טיפוסי enum

6.5.pdf

תרגול עצמי בסיסי בנושא טיפוסים ברי מניה

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

הגדירו מערך בן שלושה תאים, וקראו מהמשתמש שלושה מספרים בתחום 0 עד 6. הניחו ש: 0 מייצג את לבן, 1 את כחול, 2 את ירוק,...

עתה הציגו עבור כל תא את שם הצבע השמור בו, ואת הערך המספרי המתאים לצבע זה.

כלומר אם הקלט היה: 2, 0, 3 אזי הפלט יהיה: ירוק = 2, לבן = 0, אדום = 3

6.6 מערכים תלת-ממדיים

מערכים תלת- ממדיים הם הרחבה של מערכים דו-ממדיים. אין בהם חידוש עקרוני; מנגד, הם קשים יותר לאחזקה בדימיון.

הסבר כתוב אודות מערכים תלת-ממדיים

6.6.pdf

תרגול עצמי בסיסי בנושא מערכים תלת-ממדיים

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

קראו ציונים למערך.

עתה הציגו:

א. עבור כל כיתה וכיתה כמה תלמידים נכשלו בכיתה זאת (השיגו ציון < 55)

ב. עבור כל קורס וקורס כמה תלמידים נכשלו בקורס זה.

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

6.7 אתחול מערכים (חד-ממדיים ודו-ממדיים), והסבר כי בשפת סי כל מערך הוא חד-ממדי

הסבר כתוב אודות אתחול מערכים

6.7.pdf

6.8 תרגילים

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

כמובן, שהתרגול הוא חיוני, ולא ניתן ללמוד את החומר בלי לתרגל אותו ביסודיות.

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

6.8.pdf

שאלות מבחינות בנושא מערכים דו-ממדדיים

מופיעות בסוף הפרק הבא, הדן בפונקציות