int - קרן כליף

‫מערכים ומטריצות‬
‫קרן כליף‬
!‫ נכון שזה נכון?? אז די‬,‫אגב‬
http://programmingpalace.files.wordpress.com/2011/12/smokingwarningforsoftwareengineers.jpg
2
© Keren Kalif
‫ביחידה זו נלמד‪:‬‬
‫‪ ‬מהו מערך‬
‫‪ ‬כיצד מערך נראה בזיכרון‬
‫‪ ‬גישה לאיברי המערך‬
‫‪ ‬אתחול מערך‬
‫‪ ‬חריגה מגבולות המערך‬
‫‪ ‬השמת מערכים‬
‫‪ ‬מערך דו‪-‬מימדי‬
‫‪ ‬מערך רב‪-‬מימדי‬
‫‪ ‬לולאת ‪for-each‬‬
‫‪3‬‬
‫‪© Keren Kalif‬‬
‫מוטיבציה‬
‫ מספרים ומציגה את הממוצע‬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();
...‫ או אפילו יותר‬,‫ מספרים‬100
sum = num1 + num2 + … + num20;
System.out.println(“The average is ” + sum/20.0);
}
4
© Keren Kalif
‫הגדרה‬
‫‪ ‬מערך הוא אוסף של משתנים מאותו הסוג עם שם אחד‪ ,‬ובעלי תפקיד‬
‫זהה‬
‫‪‬‬
‫דוגמא‪ :‬מערך של ‪ 20‬מספרים‬
‫‪‬‬
‫דוגמא‪ :‬מערך של ‪ 10‬תוים‬
‫‪‬‬
‫ובאופן כללי‪:‬‬
‫;]‪int[ ] numbers = new int[20‬‬
‫;]‪char[ ] letters = new char[10‬‬
‫;]‪<type>[ ] <var_name> = new <type>[SIZE‬‬
‫‪ ‬איברי המערך נשמרים ברצף בזיכרון‬
‫‪ ‬גודל המערך בזיכרון‪<*SIZE :‬גודל הטיפוס>‬
‫‪5‬‬
‫‪© Keren Kalif‬‬
‫דוגמא למערך בזיכרון‬
public static void main(String[] args) {
int x = 4;
int[ ] arr = new int[3];
char ch = ‘a’;
}
4
int:x
int[]:arr
char: ch
0
0
0
‘a’
0 ‫ערכם של איברי המערך שהוקצה הוא‬
6
© Keren Kalif
‫גישה לאיברי המערך‬
‫‪ ‬כדי שניתן יהיה להתייחס לכל איבר בנפרד ניתנו להם אינדקסים‬
‫‪ ‬האיבר הראשון בעל אינדקס ‪ ,0‬השני בעל אינדקס ‪ 1‬והאחרון עם‬
‫אינדקס ‪SIZE-1‬‬
‫‪ ‬דוגמא‪:‬‬
‫;]‪int[ ] arr = new int[3‬‬
‫;‪arr[0] = 1‬‬
‫‪ ‬הפניה לאיבר מסוים במערך היא ע"י [ ] כאשר בתוך הסוגריים יהיה‬
‫האינדקס של האיבר אליו נרצה לגשת‬
‫‪ ‬פניה לאיבר במערך היא כפניה למשתנה מטיפוס המערך‬
‫‪ ‬מתייחסים ל‪ arr[0] -‬כמו שמתייחסים ל‪int -‬‬
‫‪7‬‬
‫‪© Keren Kalif‬‬
‫ דוגמא‬- ‫גישה לאיברי המערך‬
public static void main(String[] args) {
int[] arr = new int[3];
0
4
arr[0] = 4;
int[]:arr
arr[1] = 7;
arr[2] = 3;
System.out.printf(“The values in the array: %d %d %d\n”,
arr[0], arr[1], arr[2]);
}
0
7
0
3
8
© Keren Kalif
‫מספר האיברים המערך‬
:‫ למערך ישנו נתון המעיד על גודלו‬
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
‫ לולאות‬- ‫גישה לאיברי המערך‬
,‫ מאחר ועבודה עם איברי המערך היא עבודה זהה על כל האיברים‬
‫יותר חסכוני וקל להשתמש בלולאות‬
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();
0 -‫ יתחיל מ‬i ‫נשים לב שבעבודה עם מערכים ולולאות‬
}
System.out.println("The numbers are: ");
:‫האינדקס שאיתו פונים לאיבר במערך יכול להיות‬
for (int i=0 ; i < arr.length ; i++)
)‫ מספר שלם (כמו בדוגמא הקודמת‬
System.out.printf("%d ", arr[i]);
)‫ משתנה (כמו בדוגמא זו‬
System.out.println();
arr[i+2] :‫ למשל‬,‫ ערך של ביטוי‬
:‫ניתוח זמן הריצה של תוכנית זו‬
O(main) = O(1) + O(SIZE) + O(SIZE) = O(1) + 2*O(SIZE) = O(SIZE)
10
© Keren Kalif
)2( ‫גישה לאיברי המערך – לולאות‬
..‫הפעם נרצה להדפיס את איברי המערך מהסוף להתחלה‬
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
‫ דוגמא‬- ‫גישה לאיברי המערך – לולאות‬
:‫תוכנית המוצאת את הערך המקסימלי שהוכנס‬
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int[ ] arr = new int[4];
13
0 11
0 17
0 15
0
System.out.printf("Please enter %d numbers: ", arr.length);
for (int i=0 ; i < arr.length ; i++)
int[]:arr
arr[i] = s.nextInt();
???
int: i
???
1
2
3
4
int: max
???
13
17
int max = arr[0];
for ( int i=1 ; i < arr.length ; i++ ) {
if (arr[i] > max)
max = arr[i];
}
System.out.println("The max is “ + max);
}
:‫ניתוח זמן הריצה של תוכנית זו‬
O(main) = O(1) + O(SIZE) + O(SIZE) = O(1) + 2*O(SIZE) = O(SIZE)
12
© Keren Kalif
‫מציאת האינדקס המכיל את הערך המקסימלי‬
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();
0 11
0 17
0 15
0
13
int[]:arr
int maxIndex = 0;
int: i
for ( int i=1 ; i < arr.length ; i++ ) {
???
1
2
3
4
if (arr[i] > arr[maxIndex])
int: maxIndex
???
0
2
maxIndex = i;
}
System.out.printf("The max is at index %d and its value is %d\n“,
maxIndex, arr[maxIndex]);
}
13
© Keren Kalif
‫הגדרת מערך‬
:‫ הדרכים הבאות‬2 -‫ ניתן להגדיר מערך ב‬
int[] arr1, arr2;
int arr3[], x;
// both arr1 and arr2 are arrays
// arr3 is array, x is just int
14
© Keren Kalif
‫אתחול מערך‬
‫‪ ‬כאשר מקצים מערך ערכי איבריו הוא ‪0‬‬
‫‪ ‬ניתן לאתחל את איברי המערך במקום הקצאה באחד מן האופנים‬
‫הבאים‪:‬‬
‫‪//arr[0]=5, arr[1]=3, arr[2]=1‬‬
‫;}‪int arr[] = {5, 3, 1‬‬
‫‪//arr[0]=5, arr[1]=3, arr[2]=1‬‬
‫;}‪int[] arr = {5, 3, 1‬‬
‫‪ ‬נשים לב כי רק בעת האיתחול ניתן לתת ערך לכמה איברים יחד! כל‬
‫נתינת ערך בהמשך הינה השמה‪ ,‬ולא איתחול‪ ,‬ולכן יבוצע על כל איבר‬
‫בנפרד‪.‬‬
‫‪15‬‬
‫‪© Keren Kalif‬‬
‫ הגדרת הגודל והערכים‬:‫אתחול מערך‬
:‫ עבור המערכים הבאים‬
int[ ] numbers = {5, 3, 1};
char[ ] letters = {‘m’, ‘A’, ‘k’};
:‫ הזכרון יראה כך‬
int[]: numbers
char[]: letters
5
3
1
‘m’
‘A’
‘k’
16
© Keren Kalif
‫ הדפסת היסטוגרמה של ערכי המערך‬:‫דוגמא‬
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 (int i=0 ; i < arr.length ; i++) {
System.out.print(arr[i] + “: “);
for (int j=0 ; j < arr[i] ; j++)
System.out.print("*");
System.out.println();
}
System.out.println();
}
17
© Keren Kalif
‫הגדרה‪ :‬מערך סימטרי (פלינדרום)‬
‫‪ ‬מערך שאם נקרא את ערכיו משמאל לימין או ההפך נקבל אותו הדבר‬
‫‪18‬‬
‫‪© Keren Kalif‬‬
‫והנה דוגמאות נוספות‬
‫‪19‬‬
‫‪© Keren Kalif‬‬
‫ האם איברי המערך סימטריים‬:‫דוגמא‬
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;
}
left
right
if (isSymetric)
System.out.println("The array is symetric");
else
System.out.println("The array is NOT symetric");
}
0
8
1
5
2
4
2
3
7
5
4
8
isSymetric = false
true
20
© Keren Kalif
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;
else
isSymetric = true;
}
left
right
if (isSymetric)
System.out.println("The array is symetric");
else
0
8
1
7
2
4
3
7
4
9
System.out.println("The array is NOT symetric");
}
isSymetric = false
true
21
© Keren Kalif
‫דוגמא‪ :‬היום המועדף בשבוע ‪ -‬פלט‬
‫‪ ‬בהמשך נראה מה היה קורה אם המשתמש היה מכניס ערך שאינו‬
‫בין ‪ 1‬ל‪!7-‬‬
‫‪22‬‬
‫‪© Keren Kalif‬‬
‫ היום המועדף בשבוע‬:‫דוגמא‬
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)
0
1
2
daysFrequency[day-1]++;
0 0 0
} 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]);
3
0
1
2
int: i
4
0
5
0
6
0
1
??
int[]: daysFreq
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));
}
int: day
-1
4
??
7
int: maxDayIndex
0
??
23
© Keren Kalif
‫חריגה מגבולות המערך‬
‫‪ ‬כדי לגשת לאחד מאיברי מערך בגודל ‪ N‬ניגש עם אינדקסים ‪N-1...0‬‬
‫‪ ‬כאשר ננסה לפנות לאינדקס שאינו בגבולות המערך אנו למעשה‬
‫מנסים לגשת בתא בזיכרון שאיננו יודעים מה יש בו ומה השפעתו‪,‬‬
‫וזוהי גישה לא חוקית לשטח בזיכרון‬
‫;]‪int[] arr = new int[3‬‬
‫;‪arr[5] = 7‬‬
‫‪24‬‬
‫‪© Keren Kalif‬‬
‫חריגה מגבולות המערך (‪)2‬‬
‫‪ ‬אחריות המתכנת לפנות לתא שבגבולות המערך‬
‫‪ ‬הקומפיילר אינו מתריע על ניסיון פניה לתא שאינו בגבולות המערך‬
‫(יתכן שבזמן קומפילציה אינו ידוע מהו התא אליו מנסים לגשת)‬
‫;]‪int[] arr = new int[4‬‬
‫;‪int i‬‬
‫‪ i‬יכול להיות בין ‪ 0-3‬ואז הכל בסדר‪ ,‬או לחילופין‬
‫;)(‪i = s.nextInt‬‬
‫מספר שלילי או גדול מ‪ 3 -‬ואז אנו חורגים מגבולות‬
‫;‪arr[i] = 7‬‬
‫המערך‪ ...‬ש‬
‫‪ ‬במקרה של חריגה מגבולות המערך התוכנית תעוף עם חריגה‬
‫‪IndexOutOfBoundsException‬‬
‫‪25‬‬
‫‪© Keren Kalif‬‬
‫השמת מערכים‬
‫‪ ‬כדי לבצע השמה בין משתנים מאותו הסוג אנו משתמשים באופרטור‬
‫=‬
‫;‪int x, y=5‬‬
‫;‪x = y‬‬
‫‪ ‬עבור מערכים השמה תשנה את ההפניה‪:‬‬
‫;]‪int[] arr1={1,2,3}, arr2 = new int[3‬‬
‫;‪arr2 = arr1‬‬
‫‪3‬‬
‫‪2‬‬
‫‪1‬‬
‫‪0‬‬
‫‪0‬‬
‫‪0‬‬
‫‪int[]: arr1‬‬
‫‪int[]: arr2‬‬
‫‪ ‬העתקת ערכי המערכים תבוצע בעזרת לולאה‪ ,‬בה נעתיק איבר‪-‬איבר‬
‫‪26‬‬
‫‪© Keren Kalif‬‬
‫ דוגמא‬- ‫השמת ערכי מערכים‬
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: ");
for (int i=0 ; i < arr2.length ; i++)
System.out.printf("%d ", arr2[i]);
System.out.println();
}
27
© Keren Kalif
‫דוגמא‪ :‬קבל מספר והחזר מהי הספרה המופיעה הכי הרבה‬
‫פעמים‬
‫‪ ‬למשל‪ ,‬עבור המספר ‪ 12,327,293‬תוצג הספרה ‪ 2‬כי היא מופיעה‬
‫הכי הרבה פעמים במספר (‪ 3‬פעמים)‬
‫‪ ‬אופציה ‪ :1‬לספור באמצעות לולאה כמה פעמים בכל המספר מופיעה‬
‫הספרה ‪ ,1‬כנ"ל עבור הספרה ‪ 2‬וכו'‬
‫‪ ,10*O(n) ‬כאשר ‪ n‬הוא מספר הספרות במספר‬
‫‪10*O(n) = O(n) ‬‬
‫‪ ‬אופציה ‪ :2‬מיון דליים‬
‫‪ ,O(n) ‬כאשר ‪ n‬הוא מספר הספרות במספר‬
‫‪28‬‬
‫‪© Keren Kalif‬‬
‫הקוד‬
O(n)
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int num, maxDigit=0, maxCount=0;
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int num, counters[] = new int[10];
O(n)
System.out.print(“Enter number :”);
num = s.nextInt();
System.out.println(“Enter number :”);
num = s.nextInt();
while (num > 0) {
for (int i = 0; i < 10; i++) {
counters[num % 10]++;
int temp = num;
num /= 10;
int count = 0;
}
while (temp > 0) {
if (temp % 10 == i)
int max = 0;
count++;
for (i = 1; i < 10; i++)
temp /= 10;
if (counters[i] > counters[max])
}
max = i;
if (count > maxCount) {
maxCount = count;
System.out.println(“The digit that
maxDigit = i;
appears most is “ + max);
}
}
}
System.out.println(“The digit that appears most is “ + maxDigit);
}
29
© Keren Kalif
‫דוגמא‬
‫‪ ‬הגדר מערך של ‪ 10‬תווים‪ ,‬קלוט לתוכו נתונים מהמקלדת‪ ,‬והדפס‬
‫למסך את התווים שהוקלדו ללא חזרות‪ ,‬וכן את כמות התווים השונים‬
‫‪ ‬דוגמא‪ :‬אם המשתמש הכניס את התווים הבאים‪:‬‬
‫‪a 0 ? T T 0 $ a T x‬‬
‫‪ ‬אזי התכנית תודיע שיש ‪ 6‬תווים שונים ותדפיס למסך‪:‬‬
‫‪a 0 ? T $ x‬‬
‫‪30‬‬
‫‪© Keren Kalif‬‬
‫אסטרטגיית הפתרון‬
‫‪ ‬המשתנים בהם נשתמש‪:‬‬
‫‪ :counter ‬תפקידו לספור את כמות התווים השונים‬
‫‪ :hasAppear ‬דגל שתפקידו לדעת האם תו כבר הופיע בתווים שלפניו‬
‫‪ ‬האלגוריתם‪:‬‬
‫‪ ‬אפס ‪counter‬‬
‫‪ ‬עבור כל תו במערך‪:‬‬
‫‪ ‬אפס דגל‬
‫‪ ‬עבור כל אחד מהתווים שלפניו במערך וכל עוד הדגל לא סומן‪:‬‬
‫‪ ‬אם התו הנבדק והתו הנוכחי זהים‪:‬‬
‫‪‬‬
‫סמן את הדגל (כדי להפסיק את לולאת בדיקת התווים שלפניו)‬
‫‪ ‬אם הדגל נשאר כבוי‪ ,‬הדפס את התו למסך והגדל את ה‪counter -‬‬
‫‪31‬‬
‫‪© Keren Kalif‬‬
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int count=0;
boolean hasAppear = false;
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++;
counter -‫ונגדיל את ה‬
{
{
System.out.printf("\nThere were %d different letters\n”, count);
}
32
© Keren Kalif
‫מערך דו‪-‬מימדי ‪ -‬מוטיבציה‬
‫‪ ‬כדי לשמור ציונים של ‪ 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‬‬
‫‪33‬‬
‫‪© Keren Kalif‬‬
‫מערך דו‪-‬מימדי‬
‫‪ ‬בהגדרת מערך חד‪-‬מימדי מגדירים את מספרהתאים בו (מספר‬
‫העמודות)‪:‬‬
‫]‪int[] arr = new int[4]; arr[0] arr[1] arr[2] arr[3‬‬
‫‪ ‬בהגדרת מערך דו‪-‬מימדי נגדיר את מספר התאים בו ע"י ציון מספר‬
‫השורות ומספר העמודות‪:‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫]‪[0][3‬‬
‫]‪[1][3‬‬
‫]‪[0][2‬‬
‫]‪[1][2‬‬
‫]‪[0][1‬‬
‫]‪[1][1‬‬
‫]‪[0][0‬‬
‫;]‪int[][] arr = new int[2][4‬‬
‫]‪[1][0‬‬
‫‪ ‬מערך דו‪-‬מימדי הוא למעשה מטריצה‪ ,‬או ניתן להסתכל עליו כמערך‬
‫של מערכים‬
‫‪34‬‬
‫‪© Keren Kalif‬‬
‫מימדי‬-‫הגדרת מערך דו‬
:‫מימדי הגדרנו למשל‬-‫ כדי להגדיר מערך חד‬
double[] numbers = new double[4];
:‫ובאופן כללי‬

type[] <name> = new type[SIZE];
:‫מימדי נגדיר למשל‬-‫ כדי להגדיר מערך דו‬
double[][] numbers = new double[2][4];
:‫ ובאופן כללי‬
type[][] <name> = new type[ROWS][COLS];
35
© Keren Kalif
‫מערך דו‪-‬מימדי‬
‫ פניה לאיבר‬‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫‪arr‬‬
‫]‪[0][3‬‬
‫]‪[1][3‬‬
‫]‪[0][2‬‬
‫]‪[1][2‬‬
‫]‪[0][1‬‬
‫]‪[1][1‬‬
‫]‪[0][0‬‬
‫;]‪int[][] arr = new int[2][4‬‬
‫]‪[1][0‬‬
‫‪ ‬כדי לפנות לאיבר במערך דו‪-‬מימדי צריך לציין את מספר השורה ואת‬
‫מספר העמודה של האיבר אשר איתו אנו רוצים לעבוד‬
‫‪ ‬למשל‪ ,‬כדי לשנות את ערכו של האיבר בשורה השנייה בעמודה השלישית‪:‬‬
‫;‪arr[1][2] = 5‬‬
‫‪ ‬למשל‪ ,‬כדי לשנות את ערכו של האיבר בשורה הראשונה בעמודה הראשונה‪:‬‬
‫;‪arr[0][0] = 5‬‬
‫‪36‬‬
‫‪© Keren Kalif‬‬
‫ מספר האיברים‬int[][] arr = new int[2][4];
arr
arr
arr
arr
arr
arr
arr
arr
[0][0]
[1][0]
[0][1]
[1][1]
[0][2]
[1][2]
‫מימדי‬-‫מערך דו‬
[0][3]
[1][3]
arr.length :‫ כדי לדעת כמה שורות יש‬
arr[0].length :‫ כדי לדעת כמה איברים יש בשורה‬
37
© Keren Kalif
‫מערך דו‪-‬מימדי – דוגמא‪ :‬קליטת ציונים לכמה‬
‫כיתות והדפסתם ‪ -‬פלט‬
‫‪38‬‬
‫‪© Keren Kalif‬‬
‫ קליטת ציונים לכמה‬:‫מימדי – דוגמא‬-‫מערך דו‬
‫כיתות והדפסתם‬
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[0].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:");
for (int i=0 ; i < grades.length ; i++) {
System.out.printf("Class #%d: ", i+1);
for (int j=0 ; j < grades[i].length ; j++)
System.out.print(grades[i][j] + “ “);
System.out.println();
}
}
39
© Keren Kalif
‫מערך דו‪-‬מימדי – דוגמא‪ :‬קליטת ציונים לכמה‬
‫כיתות והדפסת הממוצע ‪ -‬פלט‬
‫‪40‬‬
‫‪© Keren Kalif‬‬
‫ קליטת ציונים לכמה‬:‫מימדי – דוגמא‬-‫מערך דו‬
‫כיתות והדפסת הממוצע‬
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[NUM_CLASSES];
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/STUDENTS_IN_CLASS;
}
System.out.println("The average for each classe:");
for (int i=0 ; i < average.length ; i++)
System.out.printf("Average for class #%d: %f\n", i+1, average[i]);
}
41
© Keren Kalif
‫מערך דו‪-‬מימדי – ייצוגו בזיכרון‬
‫‪ ‬מערך דו‪-‬מימדי נשמר בזכרון כמערך של מערכים‪:‬‬
‫;]‪int [][] arr = new arr[2][3‬‬
‫‪int[][]: arr‬‬
‫]‪arr[1][2‬‬
‫‪42‬‬
‫‪© Keren Kalif‬‬
‫]‪arr[1][1‬‬
‫]‪arr[1][0‬‬
‫]‪arr[0][2‬‬
‫]‪arr[0][1‬‬
‫]‪arr[0][0‬‬
‫מערך דו‪-‬מימדי ‪ -‬איתחול‬
‫‪ ‬ניתן לאתחל מערך דו‪-‬מימדי באופן הבא‪:‬‬
‫;}}‪int [][] numbers = { {1,2,3}, {4,5,6‬‬
‫;)‪System.out.println(numbers.length‬‬
‫‪//  2‬‬
‫‪System.out.println(numbers[0].length); //  3‬‬
‫‪int[][]: numbers‬‬
‫‪6‬‬
‫‪5‬‬
‫‪4‬‬
‫‪3‬‬
‫‪2‬‬
‫‪1‬‬
‫‪ ‬ומכאן ניתן לראות כי ניתן לייצר מערך של מערכים שאורכי שורותיו‬
‫שונים!‬
‫‪43‬‬
‫‪© Keren Kalif‬‬
‫מימדי מאותחל בשורות באורך שונה‬-‫מערך דו‬
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
int[][]: numbers
1
2
3
4
5
6
7
‫מימדי שאורכי שורותיו שווים נקרא מטריצה מלבנית‬-‫מערך דו‬
jagged ‫מימדי שאורכי שורותיו שונים נקרא מטריצה‬-‫מערך דו‬
44
© Keren Kalif
‫מימדי מוקצה בשורות באורך שונה‬-‫מערך דו‬
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("How many lines? ");
int lines = s.nextInt();
int: lines
2
int: cols
3
4
int[][]: numbers
0
0
0
0
0
0
0
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];
}
}
45
© Keren Kalif
‫ מציאת סכום איברי‬:‫מימדי – דוגמא‬-‫מערך דו‬
‫האלכסון של מטריצה ריבועית‬
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();
//}
:)‫ניתוח זמן הריצה של תוכנית זו (ללא לולאת הפלט‬
O(main) = O(1) + SIZE*O(SIZE) = O(SIZE2)
// 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(;
}
46
© Keren Kalif
‫ מציאת סכום איברי‬:‫מימדי – דוגמא‬-‫מערך דו‬
)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;
:)‫ניתוח זמן הריצה של תוכנית זו (ללא לולאת הפלט‬
O(main) = O(1) + O(SIZE) = O(SIZE)
//System.out.println("The matrix is:");
,‫ הדוגמאות פותרות בדרך שונה את אותה הבעיה‬2
//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);
}
47
© Keren Kalif
‫ הדפסת הסכום של כל‬:‫מימדי – דוגמא‬-‫מערך דו‬
‫עמודה‬
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:"); O(main) =
for (int i=0 ; i < matrix.length ; i++) { O(1) + ROWS*O(COLS) + COLS*O(ROWS) =
for (int j=0 ; j < matrix[i].length ; O(ROWS*COLS)
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);
}
48
© Keren Kalif
‫ הכנסת מספרים למטריצה‬:‫מימדי – דוגמא‬-‫מערך דו‬
‫בצורת נחש‬
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--)
matrix[i][j] = value++;
{
// 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();
{
{
49
© Keren Kalif
‫מערך רב‪-‬מימדי‬
‫‪ ‬עד כה ראינו מערכים חד‪-‬מימדיים ומערכים דו‪-‬מימדיים‬
‫‪ ‬ניתן להרחיב את ההגדרה לכל מספר סופי של מימדים‬
‫‪ ‬למשל‪ :‬מערך תלת –מימדי‬
‫;]‪int[][][] matrix = new int[LENGTH][HEIGHT][DEPTH‬‬
‫‪ ‬דוגמא לשימוש‪ :‬נרצה לשמור ממוצע ציונים עבור ‪ 5‬בתי‪-‬ספר‪ ,‬כאשר בכל‬
‫בית‪-‬ספר יש ‪ 10‬כיתות‪ ,‬ובכל כיתה ‪ 30‬סטודנטים‪:‬‬
‫;]‪double[][][] average = new int[5][10][30‬‬
‫‪ ‬במקרה זה נשתמש בלולאה‪ ,‬בתוך לולאה‪ ,‬בתוך לולאה‪..‬‬
‫‪50‬‬
‫‪© Keren Kalif‬‬
51
© 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();
}
System.out.println();
}
}
‫לולאת‬
‫‪FOR-EACH‬‬
‫‪ ‬ראינו שניתן לעבור על ערכי המערך בלולאה באמצעות פנייה לתוכן‬
‫שבאינדקס מסויים‪:‬‬
‫)‪for (int i=0 ; i < arr.length ; i++‬‬
‫;)“ “ ‪System.out.print(arr[i] +‬‬
‫‪ ‬ניתן לעבור על איברי המערך ללא אינדקס‪:‬‬
‫‪52‬‬
‫‪© Keren Kalif‬‬
‫ביחידה זו למדנו‪:‬‬
‫‪ ‬מהו מערך‬
‫‪ ‬כיצד מערך נראה בזיכרון‬
‫‪ ‬גישה לאיברי המערך‬
‫‪ ‬אתחול מערך‬
‫‪ ‬חריגה מגבולות המערך‬
‫‪ ‬השמת מערכים‬
‫‪ ‬מערך דו‪-‬מימדי‬
‫‪ ‬מערך רב‪-‬מימדי‬
‫‪ ‬לולאת ‪for-each‬‬
‫‪53‬‬
‫‪© Keren Kalif‬‬
‫תרגילי חימום‪:‬‬
‫‪.1‬‬
‫‪.2‬‬
‫‪.3‬‬
‫‪.4‬‬
‫‪.5‬‬
‫‪.6‬‬
‫הגדר מערך בגודל ‪ 10‬של מספרים שלמים וקלוט לתוכו ערכים‪ .‬הצג‬
‫רק ערכים שהם זוגיים‪.‬‬
‫הגדר מערך בגודל ‪ 10‬של תווים וקלוט לתוכו ערכים‪ .‬הצג את‬
‫האינדקסים שבתוכם ישנו תו שהוא אות גדולה‪.‬‬
‫הגדר מערך של מספרים בגודל ‪ 10‬ושים בתוכו לפי הסדר ערכים‬
‫שהם כפולות של ‪ :3‬כלומר הערכים ‪ 6 ,3 ,0‬וכו'‪.‬‬
‫הגדר מערך של מספרים שלמים וקלוט לתוכו ערכים‪ .‬הגדל ב‪ 1 -‬את‬
‫הערכים שנמצאים במיקומיים זוגיים (‪ 4 ,2 ,0‬וכו')‪.‬‬
‫הגדר מערך של מספרים שלמים בגודל ‪ 10‬וקלוט לתוכו ערכים‪.‬‬
‫הגדל ב‪ 1 -‬את הערכים שנמצאים במיקומיים זוגיים (‪ 4 ,2 ,0‬וכו')‬
‫ואח"כ הקטן ב‪ 1-‬את הערכים שנמצאים במיקומים שהם כפולה של‬
‫‪ 6 ,3 ,0( 3‬וכו')‪.‬‬
‫‪54‬‬
‫‪© Keren Kalif‬‬
‫תרגילי חימום‪:‬‬
‫‪.6‬‬
‫‪.7‬‬
‫‪.8‬‬
‫‪.9‬‬
‫‪.10‬‬
‫הגדר מערך של תווים וקלוט לתוכו ערכים‪ ,‬וכן קלוט תו נוסף‪ .‬הצג‬
‫כמה פעמים התו הנוסף שהתקבל מופיע במערך‪.‬‬
‫הגדר שני מערכים של מספרים שלמים בגודל ‪ 5‬כל אחד‪ .‬קלוט‬
‫ערכים לתוך המערך הראשון ואז קלוט ערכים לתוך המערך השני‪.‬‬
‫הצג את המיקומים אשר הערכים בהם בשני המערכים זהים‪.‬‬
‫הגדר ‪ 3‬מערכים של מספרים שלמים בגודל ‪ 5‬כל אחד‪ .‬קלוט ערכים‬
‫לתוך המערכים הראשון והשני‪ .‬שים בכל איבר במערך השלישי את‬
‫סכום האיברים במיקומים התואמים במערכים הראשון והשני‪.‬‬
‫הגדר מערך של ‪ 5‬תווים וקלוט לתוכו ערכים‪ .‬בדוק האם כל התווים‬
‫שהוקלדו למערך זהים והציגו הודעה מתאימה‪.‬‬
‫הגדר מערך של ‪ 5‬מספרים שלמים וקלוט לתוכו ערכים‪ .‬בדוק האם‬
‫ערך כל איבר גדול מערך האיבר שלפניו והצג בסוף הודעה מתאימה‪.‬‬
‫‪55‬‬
‫‪© Keren Kalif‬‬
‫תרגיל ‪:1‬‬
‫‪ ‬כתוב תוכנית המגדירה מערך בגודל ‪ 10‬של מספרים שלמים‬
‫‪ ‬קלוט ערכים מהמשתמש‪ ,‬והדפס את האינדקסים של האיברים‬
‫שערכם שווה לערך המינימלי במערך‬
‫‪ ‬כמו כן יש להדפיס את מספר האינדקסים שבתוכם יש ערך השווה‬
‫לערך המינימלי‬
‫‪ ‬דוגמא‪:‬‬
‫‪6‬‬
‫‪14 12 14 12 5 14 6‬‬
‫‪5‬‬
‫‪5‬‬
‫עבור המערך‬
‫‪ ‬יש להדפיס ‪( 5 8 9‬כי ‪ 5‬הוא המינימלי והוא נמצא באינדקסים אלו)‬
‫‪ ‬וכן להדפיס את הערך ‪ ,3‬מאחר והערך המינימלי מופיע ‪ 3‬פעמים‪.‬‬
‫‪9‬‬
‫‪56‬‬
‫‪© Keren Kalif‬‬
‫‪8‬‬
‫‪7‬‬
‫‪6‬‬
‫‪5‬‬
‫‪4‬‬
‫‪3‬‬
‫‪2‬‬
‫‪1‬‬
‫‪0‬‬
‫תרגיל ‪:2‬‬
‫‪ ‬כתוב תוכנית והגדר בה מטריצה ריבועית של תווים בגודל ‪SIZE‬‬
‫‪ ‬יש לשים את התו '*' על איברי האלכסון הראשי והמשני ורווח בשאר‬
‫האיברים (לדמות את הצורה ‪)X‬‬
‫‪ ‬הדפס את המטריצה‬
‫‪ ‬למשל‪ ,‬עבור ‪ SIZE=5‬המטריצה תראה כך‪:‬‬
‫*‬
‫*‬
‫*‬
‫*‬
‫*‬
‫*‬
‫*‬
‫‪57‬‬
‫‪© Keren Kalif‬‬
‫*‬
‫*‬
‫תרגיל ‪:3‬‬
‫‪ ‬כתוב תוכנית והגדר בה מטריצה בגודל ‪ ROWSxCOLS‬של מספרים‬
‫‪ ‬קלוט לתוכה ערכים מהמקלדת‬
‫‪ ‬קלוט מהמשתמש מספר והדפס את האינדקס של העמודה בה‬
‫המספר שהוקלד מופיע הכי הרבה פעמים‬
‫‪‬‬
‫‪‬‬
‫אם התו כלל לא מופיע במטריצה יש לתת הודעה מתאימה‬
‫שימו לב‪ :‬אין לעבור על המטריצה בהתחלה כדי לבדוק זאת!‬
‫‪ ‬למשל‪ ,‬עבור המטריצה הבאה והמספר ‪ 3‬יוצג ‪ 2‬כי המספר ‪ 3‬מופיע‬
‫הכי הרבה פעמים בעמודה ‪2‬‬
‫‪58‬‬
‫‪© Keren Kalif‬‬
‫‪8‬‬
‫‪1‬‬
‫‪3‬‬
‫‪9‬‬
‫‪1‬‬
‫‪2‬‬
‫‪7‬‬
‫‪5‬‬
‫‪2‬‬
‫‪0‬‬
‫‪3‬‬
‫‪4‬‬
‫‪3‬‬
‫‪3‬‬
‫‪6‬‬