510 likes | 679 Views
מבוא למדעי המחשב. תרגול מספר 6. חזרה על נושאים שנלמדו. כיצד ניתן לכתוב לולאה המדפיסה מספרים מ 1 עד 10 ע"י לולאת While Do-While For. חזרה על נושאים שנלמדו. מה יהיה הפלט של התוכנית הבאה : int k=4; while (k-- > 0) printf("%d",k); printf("%d",k);. חזרה על נושאים שנלמדו.
E N D
מבוא למדעי המחשב תרגול מספר6
חזרה על נושאים שנלמדו • כיצד ניתן לכתוב לולאה המדפיסה מספרים מ 1 עד 10 ע"י לולאת • While • Do-While • For
חזרה על נושאים שנלמדו • מה יהיה הפלט של התוכנית הבאה : int k=4; while (k-- > 0) printf("%d",k); printf("%d",k);
חזרה על נושאים שנלמדו • מה עושה פקודת break ? • מה עושה פקודת continue ? • מה הפלט של התוכנית הבאה ? # include <stdio.h> int main(void) { int i,j; for (i=1; i < 10; i++) { for (j=1; j <10; j++) { if (j > i) break; putchar('*'); } putvhar('\n'); } return(0); }
הנושאים להיום • מערכים חד ממדיים • הצהרה על מערכים • ייצוג מערך בזיכרון • אופרטור [ ] • אתחול מערך (ע"י לולאה / אתחול סטטי) • שליחת מערך לפונקציה • דוגמאות • מערכים דו ממדיים
מערך • מהו מערך? • טיפוס לשמירה של מספר נתונים מאותו סוג • תחביר type name[size]; • לדוגמא • int Array[4]; • char Operations[10000];
אופרטור [ ] • על מנת לגשת לאיבר מסוים במערך, משתמשים באופרטור [ ] • האיברים במערך בגודל X ממוספרים מ 0 עד X-1 • A[i] הוא האיבר שהאינדקס שלו הוא i במערך A • מסקנה - ניתן להתייחס אל A[5] כמו אל משתנה רגיל
ייצוג בזיכרון • כיצד המערך נשמר בזיכרון המחשב? • נזכר כי כל טיפוס בשפת C תופס מספר מסוים של תאים (bytes) בזיכרון. • ראינו כי ניתן לברר כמה זיכרון כל טיפוס תופס ע"י שימוש באופרטור sizeof • המערך מיוצג בזיכרון כרצף של איבריו
חשוב מאוד!!! • לא ניתן להגדיר מערך שגודלו הוא משתנה • ביצירת משתנה חדש מטיפוס מערך, גודלו תמיד ידוע ושווה לקבוע • לצורך המחשה (לא יתקמפל) • int x = 5; • int array[x];
אתחול דינאמי של מערך #define N 100 int main(void) { int A[N], i; for (i=0; i<N; i++) A[i] = i; return 0; } #define N 100 int main(void) { int A[N], i; for (i=0; i<N; i++) scanf("%d",&A[i]); return 0; }
אתחול סטטי של מערך • דוגמאות double b[] = {1.5, 3.0, 6.7}; char c[] = {'y', 'm', 'c', 'a'}; • כאן גודל המערך נקבע לפי מספר האיברים בסוגריים המסולסלים, והאיברים מאותחלים לערכים שבסוגריים המסולסלים int array[10] = {1, 5, 6}; • שלושת האיברים הראשונים מאותחלים ל-1, 5 ו-6, ושאר האיברים מאותחלים ל-0 int array2[10] = {0};
יצירת טיפוסים חדשים • זוכרים שניתן היה ליצור טיפוס חדש(מאחד קיים) ע"י הפקודה typedef? • למי שלא זוכר - typedef double weight; • weight הוא טיפוס חדש שנוצר מאחד קיים • השימוש בטיפוס החדש? בהגדרות משתנים • weight BeforeDiet, AfterDiet;
יצירת טיפוסים חדשים • שימוש ב-typedef עם מערכים • typedef double vector[10]; • נוצר טיפוס חדש בשם vector, כעת נוכל ליצור משתנים חדשים מטיפוס vector, לדוגמא • vector grades; • וכעת grades הוא משתנה מטיפוס vector, כלומר מערך בגודל 10 של double • grades[0] = 4.6; • למה זה שימושי? הקוד ברור יותר, ויותר קל לתחזק אותו
שליחת מערך לפונקציה • עד היום קראנו לפונקציות והעברנו להם פרמטרים שהיו מספר בודד • ניתן באותו האופן, לשלוח לפונקציה מערך. # include <stdio.h> #define N 4 int ArraySum(int Array[N]); int main() { int Ar[N] = {1,4,2,6}; int Sum = ArraySum(Ar); return(1); }
תרגיל 1 • כתוב תוכנית שמקבלת 200 ציונים ומדפיסה את הציון המכסימלי, הציון הממוצע, וכמה סטודנטים קבלו מעל הממוצע # include <stdio.h> # define N 200 int main(void) { int g[N], i, sum=0, average, counter=0, max; for (i=0 ; i < N ; i++) /* read the grades into array */ if (scanf("%d", &g[i]) < 1) { printf("Input error\n"); return 1; }
תרגיל 1 for (i=0 ; i < N ; i++) /* sum */ sum += g[i]; average = sum/N; /* average */ for (i=0 ; i < N ; i++) if(g[i] > average) ++counter; /* above average */ for (i=0,max=g[0] ; i < N ; i++) max = (max < g[i]) ? g[i] : max; /* maximum grade */ printf("The maximum grade is %d\n", max); printf("The average grade is %d\n", average); printf("%d students are above the average\n", counter); return 0; }
תרגיל 2 • כתוב תוכנית שקולטת מספר חיובי שלם ומדפיסה מספר חדש המורכב מספרותיו של אותו המספר, מסודרות בסדר עולה • לדוגמא, עבור הקלט 456342 יודפס 234456 • פתרון ? על הלוח
תרגיל 3 - מיזוג מערכים • נתונים שני מערכים • A בגודל n • B בגודל m • שני המערכים מכילים מספרים מטיפוס שלם • כל מערך ממוין מהקטן לגדול • יש ליצור מערך נוסף, C, בגודל n+m, כך שיכיל את אברי A ו-B בצורה ממוינת
מיזוג מערכים • דוגמא • A = 1,4,5,5,7,8 • B = 2,3,6,8 • C = 1,2,3,4,5,5,6,7,8,8
מיזוג מערכים • האלגוריתם: • 3 אינדקסים רצים: עבור A, עבור B ועבור C • העתקת האיבר הקטן מבין האיברים ב-A וב-B לתוך C, וקידום האינדקס במערך המתאים • סיום ע"י השלמה של הערכים שנותרו
דוגמת הרצה A B C
דוגמת הרצה A B C
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
A B C דוגמת הרצה
פתרון תרגיל 3 • על הלוח
תרגיל 4 • תרגיל • באולמן יש כיתה עם 3 מנורות • כל מנורה יכולה להיות דלוקה (1) או מכובה (0) • המטרה? • להדפיס את כל מצבי התאורה האפשריים • 000,001,010,011,100,101,110,111 • כתוב תוכנית המדפיסה את כל מצבי התאורה האפשריים עבור N מנורות
אלגוריתם • רעיונות? • הפתרון טמון בלמצוא שיטה לעבור ממספר בינארי אחד לאחר • נמצא שיטה שניתן להפעיל אותה שוב ושוב, וכל פעם נקבל קונפיגורציה של מנורות שעדיין לא עברנו עליה • אם השיטה תוכל לעבור על כל האופציות מבלי לחזור על אותו מספר פעמיים, דיינו!
השיטה • כל עוד לא הדפסנו את כל האפשרויות בצע : • נדפיס את הקונפיגורציה (מספר בינארי) הנוכחית • נעבור עליה משמאל לימין • אם ניתקל בספרה אפס - נשנה אותה לאחת ונחזור לשלב 1 • אם ניתקל בספרה אחת - נשנה אותה לאפס, ונמשיך לספרה הבאה (חזור לשלב 2) • 000->100->010->110->001->101->011->111
פתרון תרגיל 4 #include <stdio.h> #define N 4 int main(void) { int S[N] = {0}; int end=0, i; while(!end) { for(i = 0; i < N-1; i++) /* print current string */ printf("%d", S[i]); putchar('\n');
פתרון תרגיל 4 for(i = N-1; i >= 0; i--) /* Generate next sequence */ if(S[i] == 0) { S[i] = 1; break; } else S[i] = 0; if(i < 0) end = 1; /* check if we printed all the sequences */ } return 0; }
מערכים דו ממדיים • הרחבה של מערך/וקטור (רשימה של מספרים) לטבלה/מטריצה • כל האיברים יהיו עדיין מאותו טיפוס • תחביר type name[#rows][#cols]; • לדוגמא int matrix[22][33] יגדיר מערך דו מימדי עם 22 שורות ו 33 עמודות
מערכים דו ממדיים • כיצד מיוצג מערך דו ממדי בזיכרון ?
מערכים דו ממדיים • כמו שהשתמשנו באופרטור [] לגשת לאיבר במערך חד ממדי, נשתמש באותו אופרטור לגשת לשורה, ואח"כ לעמודה. • לדוגמא • int matrix[4][5]; • matrix[0][0] = 1; • matrix[3][4] = 23;
דוגמא • מה עושה התוכנית הבאה? #include <stdio.h> int main(void) { int a[3][5], j, k, sum=0; for (j=0; j<3; j++) for (k=0; k<5; k++) scanf("%d",&a[j][k]); for (j=0; j<3; j++) for (k=0; k<5; k++) sum += a[j][k]; printf("The sum is: %d\n",sum); return 0; }
תרגיל • מטריצה דו מימדית NXN תיקרא מטריצת קסם אם סכום השורה ה-i שווה לסכום העמודה ה-i, לכל 0<=i<N • כתוב תוכנית הבודקת אם מערך דו מימדי הוא מטריצת קסם
פתרון #include <stdio.h> #define N 10 int main(void) { int Matrix[N][N]; int i, j, SumRow, SumCol; /* Read values into matrix */ for (i=0; i<N; i++) for (j=0; j<N; j++) scanf("%d",&a[i][j]);
פתרון for(i=0 ; i<N ; i++) { SumRow = 0; /* Calculate the sum of row i */ for(j=0 ; j<N ; j++) SumRow += Matrix[i][j]; SumCol = 0; /* Calculate the sum of column i */ for(j=0 ; j<N ; j++) SumCol += Matrix[j][i]; if(SumRow != SumCol) { printf("Not A Magic Matrix\n"); return 0; } } printf("Magic Matrix Indeed!\n"); return 0; }
סיכום • מערכים • מערכים חד ממדיים • ייצוג מערך בזיכרון • אופרטור [ ] • אתחול מערך (ע"י לולאה / אתחול סטטי) • מערכים דו ממדיים
פתרון תרגיל 2 # include <stdio.h> int main(void) { long int x; int i, A[10]={0}; scanf("%ld", &x); while (x != 0){ A[x%10]++; x /= 10; } for (i = 0; i < 10; i++) while(A[i]--) printf("%d", i); return 0; }
פתרון תרגיל 3 /* Merge A[] of size SizeA and B[] of size SizeB into C[] */ #include <stdio.h> #define SizeA 5 #define SizeB 3 int main(void) { int A[SizeA], B[SizeB], C[SizeA+SizeB]; int i=0 , j=0 , k=0 ; . . . /* read input into A[] and B[] … and assume that A and B are sorted */ . . .