Professional Documents
Culture Documents
לשפת C
מבוסס על השקפים שחוברו ע"י שי ארצי ,גיתית רוקנשטיין ,איתן
אביאור וסאהר אסמיר עבור הקורס" מבוא למדעי המחשב"
נכתב ע"י טל כהן ,עודכן ע"י יורי פקלני © .כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל
תוכנייה
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 2
מערכים רב-ממדיים
מערכים ,וקטורים ומטריצות
כדי
• התשובה :אם" מערך" הוא" וקטור" ,אז נשתמש במערך דו-ממדי
=
מספר שורות מספר עמודות = לייצג מטריצה!
גובה של מטריצה רוחב של מטריצה • למשל :
int a[5][3] = {{ 3, 12, 19},
{ 8, 1, 5},
{78, 36, 65},
{ 0, 4, 9},
;}}{ 7, 2, 6
– מגדיר ומאתחל מערך דו מימדי בעל 5 שורות ו 3-עמודות .
• כדי לגשת לאיבר במערך דו-ממדי משתמשים בשני אינדקסים .
• למשל ,בדוגמא לעיל מתקיים a[1][2] == 5 :
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 5
תמונת זיכרון
• בדיוק כמו עבור מערכים חד-ממדיים ,גם עבור מטריצות אפשר להגדיר
int a[5][3] = {{ 3, 12, 19}, מצביע לאיבר הראשון :
{ 8, 1, 5},
{78, 36, 65},
{ 0, 4, 9},
;}}{ 7, 2, 6
;]int *p = &a[0][0
• כעת ניתן לגשת לנתונים של מטריצה a גם בעזרת המצביע :p
שקולים
;]int x = a[i][j
;)int x = *(p + 3*i + j
– ” “i*3כי כדי להגיע לתחילת שורה i יש לקדם את p ב :i*width-
p p+3 p+6 p+9 p+12
100 102 104 106 108 110 112 114 116 118 120 122 124 126 128
3 12 19 8 1 5 78 36 65 0 4 9 7 2 6
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות ©
מערך דו-ממדי כפרמטר לפונקציה
• אבל אם רוצים לכתוב פונקציה שעובדת עבור מטריצה בגודל כלשהו
גובה ורוחב של
חייבים להעביר לפונקציה מצביע לאיבר הראשון ,
המטריצה :
)void f(int *p, int height, int width
• כעת ,מבחינת הפונקציה p ,הוא לא מטריצה ,אלא מצביע .
אלא יש לגשת לאיבר
• לכן בתוך הפונקציה לא ניתן להשתמש ב ,p[i][j]-
)*(p + i*width + j i,jבעזרת :
– 0 ≤ i ≤ height-1, 0 ≤ j ≤ width-1
;]int m[9][4 • הקריאה לפונקציה זו תראה כך :
;)f(&m[0][0], 9, 4
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 7
תרגיל :1 מערכים ומטריצות
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 8
הדרך לפתרון
• בשביל למצוא מהו צמד שמופיע הכי הרבה פעמים ,צריכים לספור כמה
פעמים מופיע כל צמד .
אפשרויות
• כיוון שיש 500 אפשרויות לכל מספר במערך ,יש 500*500
שונות של צמדים :
– 500צמדים שהמספר הראשון שלהם 0
– 500צמדים שהמספר הראשון שלהם 1
– ...
– 500צמדים שהמספר הראשון שלהם 499
– סה"כ .500*500
שכל איבר
• כדי לספור את מספר הצמדים ,נגדיר מטריצה m[500][500]
] m[i][jסופר כמה פעמים הצמד (i,j) מופיע במערך .arr
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 9
תרגיל – 1 פתרון
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 10
תרגיל :2 מטריצות
• ריבוע חצי-קסם הוא מערך דו-מימדי שבו סכומי השורות הם שווים .
– )אין שום דרישה לגבי העמודות או האלכסונים(
5 6 לדוגמה :מערך הבא :
3 •
3 8 3
7 -1 8
הוא ריבוע חצי-קסם ,כיוון שסכום המספרים בכל שורה הוא .14
כתבו פונקציה int is_magic(int A[N][N]) •
,
המקבלת מערך דו מימדי ומחזירה 1 במידה וזהו ריבוע חצי-קסם •
ואחרת מחזירה .0
יש להניח ש N מוגדר ב .#define •
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 11
תרגיל – 2 פתרון
• נייצג תמונה בשחור לבן ע"י מערך דו ממדי ,שכל תא בו מכיל 1 עבור
נקודה שחורה ו 0 עבור נקודה לבנה
,
• נגדיר את מטריצת השליטה של תמונה כמערך דו מימדי של שלמים
של התמונה
בו במקום ה [i][j]-מוצב הערך n אם ורק אם התא ה [i][j]
הוא נקודה שחורה וגם n-1 התאים שתחתיו הם נקודות שחורות
• כתבו פונקציה אשר מקבלת תמונה ובונה את מטריצת השליטה שלה
:
לדוגמה
פיתרון -3 תרגיל
פיתרון -4 תרגיל
ו
• ממשו פונקציה רקורסיבית המקבלת מחרוזת A ושני מערכים ריקים B
.
C
)][ void SeparateLetters(char A [], char B [], char C
ואת האותיות
• הפונקציה מעתיקה את האותיות הגדולות מ A-ל B-
הקטנות מ A-ל .C-
• בסוף הריצה B ו C צריכות להיות מחרוזות
– כלומר להסתיים ב '\0'-
• יש להניח שגודל המערכיםB ו C הוא לפחות כמו הגודל של.A
• לדוגמא עבור :
A K i 1 @ B j 7 Y 8 \0 • נקבל :
B K B Y \0
C i j \0
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 18
שאלה – 1 האלגוריתם הרקורסיבי
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 19
פתרון - 2 שאלה
void SeparateLetters(char *A, char *B, char *C)
{
if (*A == '\0') {
*B = '\0';
*C = '\0';
return;
}
if (*A >= 'a' && *A <= 'z') { /* copy small letter to B */
*B = *A;
SeparateLetters(A+1, B+1, C);
return;
}
if (*A >= 'A' && *A <= 'Z') { /* copy big letter to C */
*C = *A;
SeparateLetters(A+1, B, C+1);
return;
}
SeparateLetters(A+1, B, C); /* skip non letters */
}
.
aהוא מערך שלמים באורך n •
.
ידוע ש n -אי-זוגי •
כתבו פונקציה רקורסיבית •
)void extreme_to_middle(int a[ ], int i, int j
שתדפיס את אברי a בסדר הבא משמאל לימין : •
]a[0] a[n-1] a[1] a[n-2] … a[(n-1)/2
תרגול 9 מבוא למדעי המחשב .כל הזכויות שמורות © 21
פתרון - 2 שאלה
void extreme_to_middle(int a[], int i, int j)
{
if (j==i) {
printf("%d ", a[i]);
return;
}
printf("%d ", a[i]);
printf("%d", a[j]);
extreme_to_middle(a,i+1 j-1);
return;
}