Presentation is loading. Please wait.

Presentation is loading. Please wait.

מערכים ומטריצות קרן כליף.

Similar presentations


Presentation on theme: "מערכים ומטריצות קרן כליף."— Presentation transcript:

1 מערכים ומטריצות קרן כליף

2 אגב, נכון שזה נכון?? אז די! 2 © Keren Kalif

3 ביחידה זו נלמד: מהו מערך כיצד מערך נראה בזיכרון גישה לאיברי המערך
אתחול מערך חריגה מגבולות המערך השמת מערכים מערך דו-מימדי מערך רב-מימדי לולאת for ללא אינדקס 3 © Keren Kalif

4 מוטיבציה אם נרצה לכתוב תוכנית הקוראת 20 מספרים ומציגה את הממוצע שלהם, נצטרך להגדיר 20 משתנים: public static void main(String[] args) { Scanner s = new Scanner(System.in); int num1, num2…num20, sum=0; System.out.println(“Please insert 20 numbers: “); num1 = s.nextInt(); num2 = s.nextInt(); ….. num20 = s.nextInt(); sum = num1 + num2 + … + num20; System.out.println(“The average is ” + sum/20.0); } התוכנית מסורבלת ומייגע לכתוב אותה, בייחוד כי יתכן גם שנרצה ממוצע של 100 מספרים, או אפילו יותר... 4 © Keren Kalif

5 הגדרה מערך הוא אוסף של משתנים מאותו הסוג עם שם אחד, ובעלי תפקיד זהה
מערך הוא אוסף של משתנים מאותו הסוג עם שם אחד, ובעלי תפקיד זהה דוגמא: אוסף של 20 מספרים int[ ] numbers = new int[20]; דוגמא: אוסף של 10 תוים char[ ] letters = new char[10]; ובאופן כללי: <type>[ ] <var_name> = new <type>[SIZE]; גודל המערך בזיכרון: *SIZE<גודל הטיפוס> 5 © Keren Kalif

6 ערכם של איברי המערך שהוקצה הוא 0
דוגמא למערך בזיכרון איברי המערך נשמרים ברצף בזיכרון שנקרא heap, וב- stack ישנה רק הפניה למערך הסיבה שאיברי המערך נמצאים בשטח זיכרון אחר היא שלמעשה מערך הוא אובייקט (ילמד לעומק בהמשך), ואובייקטים ב- JAVA נשמרים על ה- heap public static void main(String[] args) { int x = 4; int[ ] arr = new int[3]; char ch = ‘a’; } int:x 4 int[]:arr char: ch ‘a’ ערכם של איברי המערך שהוקצה הוא 0 6 © Keren Kalif

7 גישה לאיברי המערך מתייחסים ל- arr[0] כמו שמתייחסים ל- int
כדי שניתן יהיה להתייחס לכל איבר בנפרד ניתנו להם אינדקסים האיבר הראשון בעל אינדקס 0, השני בעל אינדקס 1 והאחרון עם אינדקס SIZE-1 דוגמא: int[ ] arr = new int[3]; arr[0] = 25; הפניה לאיבר מסוים במערך היא ע"י [ ] כאשר בתוך הסוגריים יהיה האינדקס של האיבר אליו נרצה לגשת פניה לאיבר במערך היא כפניה למשתנה מטיפוס המערך מתייחסים ל- arr[0] כמו שמתייחסים ל- int int[]:arr 1 2 25 1 2 7 © Keren Kalif

8 גישה לאיברי המערך - דוגמא
public static void main(String[] args) { int[] arr = new int[3]; arr[0] = 4; arr[1] = 7; arr[2] = 3; System.out.printf(“The values in the array: %d %d %d\n”, arr[0], arr[1], arr[2]); } 4 7 4 4 7 3 int[]:arr 8 © Keren Kalif

9 מספר האיברים המערך למערך ישנו נתון המעיד על גודלו:
public static void main(String[] args) { int[] arr = new int[4]; System.out.printf("There are %d numbers in the array\n", arr.length); } 9 © Keren Kalif

10 גישה לאיברי המערך - לולאות
מאחר ועבודה עם איברי המערך היא עבודה זהה על כל איבריו, יותר חסכוני וקל להשתמש בלולאות public static void main(String[] args) { Scanner s = new Scanner(System.in); int[ ] arr = new int[5]; System.out.printf("Please enter %d numbers: ", arr.length); for (int i=0 ; i < arr.length ; i++) arr[i] = s.nextInt(); System.out.println("The numbers are: "); System.out.printf("%d ", arr[i]); System.out.println(); } נשים לב שבעבודה עם מערכים ולולאות לרוב i יתחיל מ- 0 האינדקס שאיתו פונים לאיבר במערך יכול להיות: מספר שלם (כמו בדוגמא הקודמת) משתנה (כמו בדוגמא זו) ערך של ביטוי, למשל: arr[i+2] ניתוח זמן הריצה של תוכנית זו: O(main) = O(1) + O(SIZE) + O(SIZE) = O(1) + 2*O(SIZE) = O(SIZE) 10 © Keren Kalif

11 גישה לאיברי המערך ולולאות | הדפסת ערכי המערך מהסוף
public static void main(String[] args) { Scanner s = new Scanner(System.in); int[ ] arr = new int[5]; System.out.printf("Please enter %d numbers: ", arr.length); for (int i=0 ; i < arr.length ; i++) arr[i] = s.nextInt(); System.out.print("The numbers are: "); for (int i=arr.length-1 ; i >= 0 ; i--) System.out.printf("%d ", arr[i]); System.out.println(); } 11 © Keren Kalif

12 גישה לאיברי המערך ולולאות | מציאת הערך המקסימלי
public static void main(String[] args) { Scanner s = new Scanner(System.in); int[ ] arr = new int[4]; System.out.printf("Please enter %d numbers: ", arr.length); for (int i=0 ; i < arr.length ; i++) arr[i] = s.nextInt(); int max = arr[0]; for ( ; ; ) { if (arr[i] > max) max = arr[i]; } System.out.println("The max is “ + max); 13 11 17 15 int[]:arr int: i 1 int: max 13 int[]:arr int: i 2 int: max 17 int[]:arr int: i 2 int: max 13 int[]:arr int: i ??? int: max 13 int[]:arr ??? int: i int: max int[]:arr int: i ??? int: max int[]:arr int: i 3 int: max 17 int[]:arr int: i 4 int: max 17 int i=1 i < arr.length i++ ניתוח זמן הריצה של תוכנית זו: O(main) = O(1) + O(SIZE) + O(SIZE) = O(1) + 2*O(SIZE) = O(SIZE) 12 © Keren Kalif

13 מציאת האינדקס שבתוכו הערך המקסימלי
int[]:arr int: i 2 int: maxIndex int[]:arr int: i 2 int: maxIndex int[]:arr int: i 3 int: maxIndex 2 int[]:arr int: i 4 int: maxIndex 2 int[]:arr int: i 1 int: maxIndex int[]:arr int: i ??? int: maxIndex public static void main(String[] args) { Scanner s = new Scanner(System.in); int[ ] arr = new int[4]; System.out.printf("Please enter %d numbers: ", arr.length); for (int i=0 ; i < arr.length ; i++) arr[i] = s.nextInt(); int maxIndex = 0; for ( ; ; ) { if (arr[i] > arr[maxIndex]) maxIndex = i; } System.out.printf("The max is at index %d and its value is %d\n“, maxIndex, arr[maxIndex]); 13 11 17 15 int i=1 i < arr.length i++ 13 © Keren Kalif

14 הגדרת מערך ניתן להגדיר מערך ב- 2 הדרכים הבאות: int[] arr1, arr2;
int arr3[], x; // both arr1 and arr2 are arrays // arr3 is array, x is just int 14 © Keren Kalif

15 אתחול מערך כאשר מקצים מערך ערכי איבריו הוא 0
ניתן לאתחל את איברי המערך במקום הקצאה באחד מן האופנים הבאים: int arr[] = {5, 3, 1}; int[] arr = {5, 3, 1}; נשים לב כי רק בעת האיתחול ניתן לתת ערך לכמה איברים יחד! כל נתינת ערך בהמשך הינה השמה, ולא איתחול, ולכן יבוצע עבור כל איבר בנפרד //arr[0]=5, arr[1]=3, arr[2]=1 //arr[0]=5, arr[1]=3, arr[2]=1 15 © Keren Kalif

16 אתחול מערכים: דוגמת הזכרון
עבור המערכים הבאים: int[ ] numbers = {5, 3, 1}; char[ ] letters = {‘m’, ‘A’, ‘k’}; הזכרון יראה כך: 5 3 1 int[]: numbers char[]: letters ‘m’ ‘A’ ‘k’ 16 © Keren Kalif

17 דוגמא: הדפסת היסטוגרמה של ערכי המערך
דוגמא: הדפסת היסטוגרמה של ערכי המערך int[]:arr int: i int: j int[]:arr int: i 1 int: j int[]:arr int: i int: j int[]:arr int: i 3 int: j int[]:arr int: i 4 int: j int[]:arr int: i 2 int: j 4 3 2 7 public static void main(String[] args) { int[] arr = {4, 3, 2, 7}; System.out.printf("There are %d numbers in the array: \n", arr.length); for ( ; ; ) { System.out.print(arr[i] + “: “); for (int j=0 ; j < arr[i] ; j++) System.out.print("*"); System.out.println(); } int i=0 i < arr.length i++ 4: **** 3: *** 2: ** 7: ******* 17 © Keren Kalif

18 מערך סימטרי (פלינדרום)
הגדרה: פלינדרום הוא מערך שאם נקרא את ערכיו משמאל לימין או מימין לשמאל נקבל ערכים בסדר זהה 18 © Keren Kalif

19 והנה דוגמאות נוספות 19 © Keren Kalif

20 דוגמא: האם איברי המערך סימטריים
public static void main(String[] args) { Scanner s = new Scanner(System.in); int arr[] = new int [5], left, right; boolean isSymetric=true; System.out.printf("Enter %d numbers: ", arr.length); for (int i=0 ; i < arr.length ; i++) arr[i] = s.nextInt(); for (left=0, right=arr.length-1; left < right && isSymetric ; left++, right--) { if (arr[left] != arr[right]) isSymetric = false; } if (isSymetric) System.out.println("The array is symetric"); else System.out.println("The array is NOT symetric"); left right 1 2 3 4 8 5 7 1 2 3 4 8 5 isSymetric = true isSymetric = false 20 © Keren Kalif

21 מה עושה הקוד הבא? קוד חביב, אך אפשר לכתוב אותו יותר קצר ופחות מסורבל
public static void main(String[] args) { int arr[] = {?, ?, ?, ?, ?}; int count = 1; for (int i = 1; i < arr.length ; i++) { if (arr[i] == arr[0]) count++; } if (count == arr.length) System.out.println("1"); else System.out.println("0"); כמובן שתחביר לא תקין, אך נניח שאלו ערכים כלשהם לצרכי התרגיל ספירת מספר האיברים שערכיהם זהים לערך האיבר הראשון אם התנאי מתקיים, משמע כל ערכי המערך זהים והתוכנית תדפיס 1, אחרת תדפיס 0 21 © Keren Kalif

22 מה עושה הקוד הבא? public static void main(String[] args) {
int arr[] = {?, ?, ?, ?, ?}; for (int i = 1; i < arr.length; i++) { if (arr[i] == arr[0]) { } else { System.out.println("0"); return; System.out.println("1"); זוהי צורת כתיבה עובדת, אבל עקומה! לא נכתוב תנאי אם הגוף שלו ריק! לידע כללי, return הינה פקודה המסיימת את ה- main באופן מיידי התוכנית מדפיסה 0 במידה וקיים ערך שאינו זהה לערך האיבר הראשון ויוצאת, כלומר התוכנית מדפיסה 1 אם ערכי כל האיברים זהים, אחרת מדפיסה 0 22 © Keren Kalif

23 שדרוג הקוד הקודם זו גרסת הקוד האופטימלית!
public static void main(String[] args) { int arr[] = {?, ?, ?, ?, ?}; for (int i = 1; i < arr.length; i++) { if (arr[i] == arr[0]) { } else { System.out.println("0"); return; System.out.println("1"); if (arr[i] != arr[0]){ System.out.println("0"); return; } לא נכתוב תנאים ריקים! אין בעיה לכתוב if בלי !else כדאי לזכור שניתן להשתמש גם בבדיקת שונה (=!) ולא רק בבדיקת שוויון (==) 23 © Keren Kalif

24 טעות נפוצה public static void main(String[] args) {
int arr[] = { ?, ?, ?, ?, ? }; for (int i = 1; i < arr.length ; i++) { if (arr[i] != arr[0]) { System.out.println("0"); return; } else { System.out.println("1"); } לא כל if חייב else! כי באופן כתיבה זו תודפס תשובה כבר אחרי הסיבוב הראשון של הלולאה, ולמעשה ייבדק רק הזוג הראשון במערך 24 © Keren Kalif

25 דוגמא: היום המועדף בשבוע - פלט
בהמשך נראה מה היה קורה אם המשתמש היה מכניס ערך שאינו בין 1 ל-7! 25 © Keren Kalif

26 דוגמא: היום המועדף בשבוע
public static void main(String[] args) { Scanner s = new Scanner(System.in); final int EXIT = -1; int daysFrequency[] = new int[7], day, maxDayIndex; do { System.out.printf("Insert the day you like most (1-7), %d to EXIT: ", EXIT); day = s.nextInt(); if (day != EXIT) daysFrequency[day-1]++; } while (day != EXIT); System.out.println("Each day and number of persons who liked it most:"); for (int i=1 ; i<=7 ; i++) System.out.printf("%d: %d\n", i, daysFrequency[i-1]); maxDayIndex = 0; for (int i=1 ; i < 7 ; i++) { if (daysFrequency[i] > daysFrequency[maxDayIndex]) maxDayIndex = i; } System.out.println("The favorite day is: “ + (maxDayIndex+1)); 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 int: i ?? int[]: daysFreq int: day int: maxDayIndex ?? -1 ?? 4 ?? 7 ?? 4 ?? -1 26 © Keren Kalif

27 חריגה מגבולות המערך כדי לגשת לאחד מאיברי מערך בגודל N ניגש עם אינדקסים N כאשר ננסה לפנות לאינדקס שאינו בגבולות המערך אנו למעשה מנסים לגשת לתא בזיכרון שאיננו יודעים מה יש בו ומה השפעתו, וזוהי גישה לא חוקית לשטח בזיכרון int[] arr = new int[3]; arr[5] = 7; 27 © Keren Kalif

28 חריגה מגבולות המערך (2) אחריות המתכנת לפנות לתא שבגבולות המערך
הקומפיילר אינו מתריע על ניסיון פניה לתא שאינו בגבולות המערך (יתכן שבזמן קומפילציה אינו ידוע מהו התא אליו מנסים לגשת) int[] arr = new int[4]; int i = s.nextInt(); arr[i] = 7; במקרה של חריגה מגבולות המערך התוכנית תעוף עם חריגה IndexOutOfBoundsException i יכול להיות בין 0-3 ואז הכל בסדר, או לחילופין מספר שלילי או גדול מ- 3 ואז אנו חורגים מגבולות המערך... ש 28 © Keren Kalif

29 השמת מערכים כדי לבצע השמה בין משתנים מאותו הסוג אנו משתמשים באופרטור =
int x, y=5; x = y; עבור מערכים השמה תשנה את ההפניה: int[] arr1={1,2,3}, arr2 = new int[3]; arr2 = arr1; העתקת ערכי המערכים תבוצע בעזרת לולאה, בה נעתיק איבר-איבר 1 2 3 int[]: arr1 int[]: arr2 29 © Keren Kalif

30 השמת ערכי מערכים - דוגמא
public static void main(String[] args) { int[] arr1 = {1,2,3}, arr2 = new int[3]; // arr2 = arr1; // DOESN'T do what we want!! System.out.print("Elements in arr2 before: "); for (int i=0 ; i < arr2.length ; i++) System.out.printf("%d ", arr2[i]); for (int i=0 ; i < arr2.length ; i++) arr2[i] = arr1[i]; System.out.print("\nElements in arr2 after: "); System.out.println(); } 30 © Keren Kalif

31 דוגמא: קבל מספר והחזר מהי הספרה המופיעה הכי הרבה פעמים
למשל, עבור המספר 12,327,293 תוצג הספרה 2 כי היא מופיעה הכי הרבה פעמים במספר (3 פעמים) אופציה 1: לספור באמצעות לולאה כמה פעמים בכל המספר מופיעה הספרה 1, כנ"ל עבור הספרה 2 וכו' 10*O(n), כאשר n הוא מספר הספרות במספר 10*O(n) = O(n) אופציה 2: מיון דליים O(n), כאשר n הוא מספר הספרות במספר 31 © Keren Kalif

32 הקוד O(n) O(n) public static void main(String[] args) {
Scanner s = new Scanner(System.in); int num, counters[] = new int[10]; System.out.print(“Enter number :”); num = s.nextInt(); while (num > 0) { counters[num % 10]++; num /= 10; } int max = 0; for (i = 1; i < 10; i++) if (counters[i] > counters[max]) max = i; System.out.println(“The digit that appears most is “ + max); O(n) public static void main(String[] args) { Scanner s = new Scanner(System.in); int num, maxDigit=0, maxCount=0; System.out.println(“Enter number :”); num = s.nextInt(); for (int i = 0; i <= 9 ; i++) { int temp = num; int count = 0; while (temp > 0) { if (temp % 10 == i) count++; temp /= 10; } if (count > maxCount) { maxCount = count; maxDigit = i; System.out.println(“The digit that appears most is “ + maxDigit); O(n) 32 © Keren Kalif

33 דוגמא: הדפסת התווים השונים במערך ומספרם
הגדר מערך של 10 תווים, קלוט לתוכו נתונים מהמקלדת, והדפס למסך את התווים שהוקלדו ללא חזרות, וכן את מספר התווים השונים דוגמא: אם המשתמש הכניס את התווים הבאים: a 0 ? T T 0 $ a T x אזי התכנית תודיע שיש 6 תווים שונים ותדפיס למסך: a 0 ? T $ x 33 © Keren Kalif

34 אסטרטגיית הפתרון a ! b a ! b counter = 1 3 2 hasAppear = false true הרעיון: עבור כל תו נבדוק אם הוא כבר הופיע בתווים שלפניו. במידה ולא נגדיל את ה- counter ונדפיס את התו המשתנים בהם נשתמש: counter: תפקידו לספור את מספר התווים השונים hasAppear: דגל שתפקידו לדעת האם תו כבר הופיע בתווים שלפניו האלגוריתם: אפס counter עבור כל תו במערך: אפס דגל עבור כל אחד מהתווים שלפניו והתו לא הופיע בתווים שלפניו (הדגל לא סומן): אם התו הנבדק והתו הנוכחי זהים: סמן את הדגל (כדי להפסיק את לולאת בדיקת התווים שלפניו) אם הדגל נשאר כבוי, הדפס את התו למסך והגדל את ה- counter 34 © Keren Kalif

35 קוד הפתרון קליטת הנתונים איפוס הדגל עבור התו הנוכחי
public static void main(String[] args) { Scanner s = new Scanner(System.in); int count=0; boolean hasAppear; char[] str = new char[10]; System.out.printf("Please enter %d chars: “, str.length); for (int i=0 ; i < str.length ; i++) str[i] = s.next().charAt(0); // print each char only once System.out.println("The chars are:”); for (int i=0 ; i < str.length ; i++) } hasAppear = false; for (int j=0 ; j < i && !hasAppear; j++) { if (str[i] == str[j]) hasAppear = true; } if (!hasAppear) } System.out.print(str[i]); count++; { System.out.printf("\nThere were %d different letters\n”, count); קוד הפתרון קליטת הנתונים איפוס הדגל עבור התו הנוכחי אם התו זהה לאחד התווים שלפניו, נדליק את הדגל אם התו לא הופיע, נדפיס אותו ונגדיל את ה- counter 35 © Keren Kalif

36 מערך דו-מימדי - מוטיבציה
כדי לשמור ציונים של 30 סטודנטים בכיתה נגדיר מערך בגודל 30: int[] grades = new int[30]; אם יש לנו 3 כיתות שעבורן נרצה לשמור ציונים של 30 סטודנטים בכיתה נצטרך להגדיר 3 מערכים: int[] grades1=new int[30], grades2=new int[30], grades3=new int[30]; אבל 3 הכיתות האלו הן גם אוסף של משתנים מאותו הסוג – מערך של מספרים בגודל 30 לכן נרצה להגדיר מערך שיש בו 3 איברים, וכל איבר הוא מערך בגודל 30: int[][] grades = new int[3][30]; 36 © Keren Kalif

37 מערך דו-מימדי בהגדרת מערך חד-מימדי מגדירים את מספר התאים (מספר העמודות): int[] arr = new int[4]; בהגדרת מערך דו-מימדי נגדיר את מספר התאים ע"י ציון מספר השורות ומספר העמודות: int[][] arr = new int[2][4]; מערך דו-מימדי הוא מערך של מערכים, אבל ניתן להתייחס אליו כעל מטריצה int[]:arr arr[0] arr[1] arr[2] arr[3] arr[0][0] arr[0][1] arr[0][2] arr[0][3] arr[0] arr[1] int[]:arr arr[1][0] arr[1][1] arr[1][2] arr[1][3] 37 © Keren Kalif

38 הגדרת מערך דו-מימדי כדי להגדיר מערך חד-מימדי הגדרנו למשל:
double[] numbers = new double[4]; ובאופן כללי: type[] <name> = new type[SIZE]; כדי להגדיר מערך דו-מימדי נגדיר למשל: double[][] numbers = new double[2][4]; type[][] <name> = new type[ROWS][COLS]; 38 © Keren Kalif

39 מערך דו-מימדי - פניה לאיבר
מערך דו-מימדי - פניה לאיבר int[][] arr = new int[2][4]; כדי לפנות לאיבר במערך דו-מימדי צריך לציין את מספר השורה ואת מספר העמודה של האיבר אשר איתו רוצים לעבוד למשל, כדי לשים את הערך 5 באיבר בשורה השנייה בעמודה השלישית: arr[1][2] = 5; למשל, כדי לשים את הערך 5 באיבר בשורה הראשונה בעמודה הראשונה: arr[0][0] = 5; arr[0][0] arr[0][1] arr[0][2] arr[0][3] arr[0] arr[1] int[]:arr arr[1][0] arr[1][1] arr[1][2] arr[1][3] 39 © Keren Kalif

40 מערך דו-מימדי - מספר האיברים
מערך דו-מימדי - מספר האיברים int[][] arr = new int[2][4]; כדי לדעת כמה שורות יש: arr.length כדי לדעת כמה איברים יש בשורה ה- 0: arr[0].length כדי לדעת כמה איברים יש בשורה ה- 1: arr[1].length כמובן שבמקרה זה מספר האיברים בכל השורות זהה arr[0][0] arr[0][1] arr[0][2] arr[0][3] arr[0] arr[1] int[]:arr arr[1][0] arr[1][1] arr[1][2] arr[1][3] 40 © Keren Kalif

41 מערך דו-מימדי – דוגמא: קליטת ציונים למספר כיתות והדפסתם - פלט
41 © Keren Kalif

42 מערך דו-מימדי – דוגמא: קליטת ציונים לכמה כיתות והדפסתם
public static void main(String[] args) { Scanner s = new Scanner(System.in); final int NUM_CLASSES=3, STUDENTS_IN_CLASS=5; int [][] grades = new int[NUM_CLASSES][STUDENTS_IN_CLASS]; System.out.printf("Please enter grades for students in %d classes:\n", grades.length); for (int i=0 ; i < grades.length ; i++) { System.out.printf("Please enter grades for %d students in class #%d:", grades[i].length, i+1); for (int j=0 ; j < grades[i].length ; j++) grades[i][j] = s.nextInt(); } System.out.println("The grades in all classes:"); System.out.printf("Class #%d: ", i+1); System.out.print(grades[i][j] + “ “); System.out.println(); 42 © Keren Kalif

43 מערך דו-מימדי – דוגמא: קליטת ציונים לכמה כיתות והדפסת הממוצע - פלט
43 © Keren Kalif

44 מערך דו-מימדי – דוגמא: קליטת ציונים לכמה כיתות והדפסת הממוצע
public static void main(String[] args) { Scanner s = new Scanner(System.in); final int NUM_CLASSES=3, STUDENTS_IN_CLASS=5; int [][] grades = new int[NUM_CLASSES][STUDENTS_IN_CLASS]; float[] average = new float[grades.length]; System.out.printf("Please enter grades for students in %d classes:\n", grades.length); for (int i=0 ; i < grades.length ; i++) { System.out.printf("Please enter grades for %d students in class #%d:", grades[i].length, i+1); int sum=0; for (int j=0 ; j < grades[i].length ; j++) { grades[i][j] = s.nextInt(); sum += grades[i][j]; } average[i] = (float)sum/grades[i].length; System.out.println("The average for each class:"); for (int i=0 ; i < average.length ; i++) System.out.printf("Average for class #%d: %f\n", i+1, average[i]); 44 © Keren Kalif

45 מערך דו-מימדי - איתחול ניתן לאתחל מערך דו-מימדי באופן הבא:
int [ ][ ] numbers = { {1,2,3}, {4,5,6}}; System.out.println(numbers.length); //  2 System.out.println(numbers[0].length); //  3 וכמובן שניתן לייצר מערך של מערכים שאורכי שורותיו שונים 1 2 3 int[][]: numbers 4 5 6 45 © Keren Kalif

46 מערך דו-מימדי מאותחל בשורות באורך שונה
int [ ][ ] numbers = { {1,2,3}, {4,5,6,7}}; System.out.println(numbers.length); //  2 System.out.println(numbers[0].length); //  3 System.out.println(numbers[1].length); //  4 1 2 3 int[][]: numbers 4 5 6 7 מערך דו-מימדי שאורכי שורותיו זהים נקרא מטריצה מלבנית מערך דו-מימדי שאורכי שורותיו שונים נקרא מטריצה jagged 46 © Keren Kalif

47 מערך דו-מימדי מוקצה בשורות באורך שונה
int: lines 2 int: cols 3 int[][]: numbers int: lines int: cols int[][]: numbers int: lines 2 int: cols 4 int[][]: numbers int: lines 2 int: cols int[][]: numbers public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.print("How many lines? "); int lines = s.nextInt(); int [][] numbers = new int[lines][]; for (int i=0 ; i < numbers.length ; i++) { System.out.print("How many elements int line # " + (i+1) + "? "); int cols = s.nextInt(); numbers[i] = new int[cols]; } 47 © Keren Kalif

48 מערך דו-מימדי – דוגמא: מציאת סכום איברי האלכסון של מטריצה ריבועית
public static void main(String[] args) { int[][] matrix = { {1,1,1,1}, {2,4,4,2}, {3,2,1,0}, {7,6,5,4} }; int sum=0; //System.out.println("The matrix is:"); //for (int i=0 ; i < matrix.length ; i++) { // for (int j=0 ; j < matrix[i].length ; j++) // System.out.printf("%d\t", matrix[i][j]); // System.out.println(); //} // calc the sum of the main diagonal for (int i=0 ; i < matrix.length ; i++) for (int j=0 ; j < matrix[i].length ; j++) if (i == j) sum += matrix[i][j]; System.out.println("The sum of the main diagonal is “ + sum); } ניתוח זמן הריצה של תוכנית זו (ללא לולאת הפלט): O(main) = O(1) + SIZE*O(SIZE) = O(SIZE2) 48 © Keren Kalif

49 מערך דו-מימדי – דוגמא: מציאת סכום איברי האלכסון של מטריצה ריבועית (2)
מערך דו-מימדי – דוגמא: מציאת סכום איברי האלכסון של מטריצה ריבועית (2) public static void main(String[] args) { int[][] matrix = { {1,1,1,1}, {2,4,4,2}, {3,2,1,0}, {7,6,5,4} }; int sum=0; //System.out.println("The matrix is:"); //for (int i=0 ; i < matrix.length ; i++) { // for (int j=0 ; j < matrix[i].length ; j++) // System.out.printf("%d\t", matrix[i][j]); // System.out.println(); //} // calc the sum of the main diagonal for (int i=0 ; i < matrix.length ; i++) sum += matrix[i][i]; System.out.println("The sum of the main diagonal is “ + sum); } ניתוח זמן הריצה של תוכנית זו (ללא לולאת הפלט): O(main) = O(1) + O(SIZE) = O(SIZE) 2 הדוגמאות פותרות בדרך שונה את אותה הבעיה, אבל בסיבוכיות שונה. לכן נעדיף פתרון זה אשר הסיבוכיות שלו קטנה בסדר גודל שלם מהפתרון הקודם! 49 © Keren Kalif

50 מערך דו-מימדי – דוגמא: הדפסת הסכום של כל עמודה
public static void main(String[] args) { int[][] matrix = { {1,1,1,1}, {2,4,4,2}, {7,6,5,4} }; System.out.println("The matrix is:"); for (int i=0 ; i < matrix.length ; i++) { for (int j=0 ; j < matrix[i].length ; j++) System.out.printf("%d\t", matrix[i][j]); System.out.println(); } for (int i=0 ; i < matrix[0].length ; i++) { int sum=0; for (int j=0 ; j < matrix.length ; j++) sum += matrix[j][i]; System.out.printf("The sum of elements in column #%d %d\n", i+1, sum); ניתוח זמן הריצה של תוכנית זו: O(main) = O(1) + ROWS*O(COLS) + COLS*O(ROWS) = O(ROWS*COLS) 50 © Keren Kalif

51 מערך דו-מימדי – דוגמא: הכנסת מספרים למטריצה בצורת נחש
public static void main(String[] args) { int[][] matrix = new int[8][5]; int value = 1; for (int i=0 ; i < matrix.length ; i++) } if (i%2 == 0) for (int j=0 ; j < matrix[i].length; j++) matrix[i][j] = value++; else for (int j= matrix[i].length -1 ; j >= 0 ; j--) { // print matrix for (int i=0 ; i < matrix.length; i++) } for (int j=0 ; j < matrix[i].length ; j++) System.out.printf("%4d", matrix[i][j]); System.out.println(); 51 © Keren Kalif

52 מערך רב-מימדי עד כה ראינו מערכים חד-מימדיים ומערכים דו-מימדיים
ניתן להרחיב את ההגדרה לכל מספר סופי של מימדים למשל: מערך תלת –מימדי int[][][] matrix = new int[LENGTH][HEIGHT][DEPTH]; דוגמא לשימוש: נרצה לשמור ממוצע ציונים עבור 5 בתי-ספר, כאשר בכל בית-ספר יש 10 כיתות, ובכל כיתה 30 סטודנטים: int[][][] average = new int[5][10][30]; במקרה זה נשתמש בלולאה, בתוך לולאה, בתוך לולאה.. 52 © Keren Kalif

53 מערך רב-מימדי – דוגמאת נתוני בתי- הספר
53 © Keren Kalif מערך רב-מימדי – דוגמאת נתוני בתי- הספר public static void main(String[] args) { float[][][] grades = { { {90, 100, 95, 88}, {87, 70, 90, 98} }, { {88, 75, 80, 60}, {55, 87, 90, 82} }, { {60, 91, 40, 95}, {77, 66, 88, 99} } }; for (int i=0 ; i < grades.length; i++) { System.out.printf("Classes in school #%d:\n", i+1); for (int j=0 ; j < grades[i].length; j++) { System.out.printf(" Grades in class #%d: ", j+1); for (int k=0 ; k < grades[i][j].length; k++) System.out.printf("%.2f ", grades[i][j][k]); System.out.println(); }

54 לולאת for ללא אינדקס ראינו שניתן לעבור על ערכי המערך בלולאה באמצעות פנייה לתוכן שבאינדקס מסויים: for (int i=0 ; i < arr.length ; i++) System.out.print(arr[i] + “ “); ניתן לעבור על איברי המערך ללא אינדקס: 54 © Keren Kalif

55 ביחידה זו למדנו: מהו מערך כיצד מערך נראה בזיכרון גישה לאיברי המערך
אתחול מערך חריגה מגבולות המערך השמת מערכים מערך דו-מימדי מערך רב-מימדי לולאת for ללא אינדקס 55 © Keren Kalif

56 תרגילי חימום: הגדר מערך בגודל 10 של מספרים שלמים וקלוט לתוכו ערכים. הצג רק ערכים שהם זוגיים. הגדר מערך בגודל 10 של תווים וקלוט לתוכו ערכים. הצג את האינדקסים שבתוכם ישנו תו שהוא אות גדולה. הגדר מערך של מספרים בגודל 10 ושים בתוכו לפי הסדר ערכים שהם כפולות של 3: כלומר הערכים 0, 3, 6 וכו'. הגדר מערך של 10 מספרים שלמים וקלוט לתוכו ערכים. הגדל ב- 1 את הערכים שנמצאים במיקומיים זוגיים (0, 2, 4 וכו'). הגדר מערך של מספרים שלמים בגודל 10 וקלוט לתוכו ערכים. הגדל ב- 1 את הערכים שנמצאים במיקומיים זוגיים (0, 2, 4 וכו') ואח"כ הקטן ב-1 את הערכים שנמצאים במיקומים שהם כפולה של 3 (0, 3, 6 וכו'). 56 © Keren Kalif

57 תרגילי חימום: הגדר מערך של תווים וקלוט לתוכו ערכים, וכן קלוט תו נוסף. הצג כמה פעמים התו הנוסף שהתקבל מופיע במערך. הגדר שני מערכים של מספרים שלמים בגודל 5 כל אחד. קלוט ערכים לתוך המערך הראשון ואז קלוט ערכים לתוך המערך השני. הצג את המיקומים אשר הערכים בהם בשני המערכים זהים. הגדר 3 מערכים של מספרים שלמים בגודל 5 כל אחד. קלוט ערכים לתוך המערכים הראשון והשני. שים בכל איבר במערך השלישי את סכום האיברים במיקומים התואמים במערכים הראשון והשני. הגדר מערך של 5 תווים וקלוט לתוכו ערכים. בדוק האם כל התווים שהוקלדו למערך זהים והציגו הודעה מתאימה. הגדר מערך של 5 מספרים שלמים וקלוט לתוכו ערכים. בדוק האם ערך כל איבר גדול מערך האיבר שלפניו והצג בסוף הודעה מתאימה. 57 © Keren Kalif

58 תרגיל 1: הדפסת האינדקסים של הערך המינימלי
תרגיל 1: הדפסת האינדקסים של הערך המינימלי כתוב תוכנית המגדירה מערך בגודל 10 של מספרים שלמים קלוט ערכים מהמשתמש, והדפס את האינדקסים של האיברים שערכם שווה לערך המינימלי במערך כמו כן יש להדפיס את מספר האינדקסים שבתוכם יש ערך השווה לערך המינימלי דוגמא: עבור המערך יש להדפיס (כי 5 הוא המינימלי והוא נמצא באינדקסים אלו) וכן להדפיס את הערך 3, מאחר והערך המינימלי מופיע 3 פעמים. 1 2 3 4 5 6 7 8 9 14 12 58 © Keren Kalif

59 תרגיל 2: האם איברי מערך מהווים סדרה חשבונית
תרגיל 2: האם איברי מערך מהווים סדרה חשבונית כתבו תוכנית המגדירה מערך בגודל 10 של מספרים שלמים קלוט ערכים מהמשתמש הצג האם ערכי המערך מהווים סדרה חשבונית דוגמאות: 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22 24 X 1 2 3 4 5 6 7 8 9 10 12 14 17 18 20 22 24 59 © Keren Kalif

60 תרגיל 3: השמת כוכביות על אלכסוני המטריצה
כתוב תוכנית והגדר בה מטריצה ריבועית של תווים בגודל SIZE יש לשים את התו '*' על איברי האלכסון הראשי והמשני ורווח בשאר האיברים (לדמות את הצורה X) הדפס את המטריצה למשל, עבור SIZE=5 המטריצה תראה כך: * 60 © Keren Kalif

61 תרגיל 4: העמודה בה מספר הופיע הכי הרבה פעמים
כתוב תוכנית והגדר בה מטריצה בגודל ROWSxCOLS של מספרים קלוט לתוכה ערכים מהמקלדת קלוט מהמשתמש מספר והדפס את האינדקס של העמודה בה המספר שהוקלד מופיע הכי הרבה פעמים אם התו כלל לא מופיע במטריצה יש לתת הודעה מתאימה שימו לב: אין לעבור על המטריצה בהתחלה כדי לבדוק זאת! למשל, עבור המטריצה הבאה והמספר 3 יוצג 2 כי המספר 3 מופיע הכי הרבה פעמים בעמודה 2 1 9 3 8 2 5 7 6 4 61 © Keren Kalif


Download ppt "מערכים ומטריצות קרן כליף."

Similar presentations


Ads by Google