SEN1001 · 9. hafta · Multidimensional Arrays

İki boyutlu diziler (2D arrays)

Satır ve sütunlardan oluşan tablolar: oluşturma, m.length ile m[r].length, iç içe döngüyle gezinme, satır/sütun toplamı, köşegen, transpoze ve düzensiz (ragged) diziler. Finalde iz sürme ve metot yazma olarak gelir.

two-dimensional arraymultidimensional arrayrowcolumnrow-major ordernested looparray of arraysragged arraymain diagonaltransposeArrays.deepToString

Bazı veriler doğal olarak tablo şeklindedir: bir sınıfın her öğrencisinin her sınavdaki notu, satranç tahtası, sinema salonundaki koltuklar, bir matris. Java’da bunun için iki boyutlu dizi (two-dimensional array) kullanılır. Yeni bir kavram az, ama 1D dizideki kuralları iki indeksle birlikte doğru uygulamak gerekir. Sınavda tipik soru: “bu iç içe döngü 2D diziyi gezince ne basar?” ve “satır/sütun toplamını döndüren metot yaz”.

Altın kurallar:

  1. m[r][c]: önce satır (row), sonra sütun (column).
  2. m.length satır sayısı, m[r].length o satırın sütun sayısı.
  3. Dış döngü satır, iç döngü sütun (satır satır gezinme, row-major).
  4. 2D dizi, dizilerin dizisidir. m[r] başlı başına bir 1D dizi.
  5. Sütun sınırında sabit sayı değil m[r].length yaz. Düzensiz dizilerde de doğru çalışır.

Oluşturma

int[][] grid = new int[3][4];        // 3 satır, 4 sütun, hepsi 0
grid[0][1] = 5;
grid[2][3] = 9;
System.out.println(grid.length + " " + grid[0].length + " " + grid[0][1] + " " + grid[1][1]);
3 4 5 0
          sütun 0   sütun 1   sütun 2   sütun 3
satır 0      0         5         0         0
satır 1      0         0         0         0
satır 2      0         0         0         9

Değerleri baştan biliyorsan başlangıç listesi: her iç süslü parantez bir satır.

int[][] m = {
    {1, 2, 3},
    {4, 5, 6}
};

Gezinme ve yazdırma

for (int r = 0; r < m.length; r++) {
    for (int c = 0; c < m[r].length; c++) {
        System.out.print(m[r][c] + " ");
    }
    System.out.println();               // satır bitti
}
System.out.println(m[1][0] + " " + m[0][2] + " " + m.length + " " + m[1].length);
System.out.println(Arrays.toString(m[1]));
System.out.println(Arrays.deepToString(m));
1 2 3 
4 5 6 
4 3 2 3
[4, 5, 6]
[[1, 2, 3], [4, 5, 6]]

m[1] ikinci satırın tamamı, yani {4, 5, 6} dizisi; bu yüzden Arrays.toString(m[1]) çalışıyor. Bütün tabloyu tek satırda görmek için Arrays.deepToString.

Hizalı bir tablo için printf genişliği kullan:

for (int[] row : m) {
    for (int v : row) System.out.printf("%4d", v * 10);
    System.out.println();
}
  10  20  30
  40  50  60

Enhanced for iç içe de kullanılır: dıştaki değişkenin tipi int[] (bir satır), içtekinin tipi int (bir hücre).

Sütun sütun gezinme

Döngülerin yerini değiştirirsen tablo sütun sütun okunur. Dikdörtgen dizide sütun sınırı için m[0].length kullanılır:

for (int c = 0; c < m[0].length; c++) {
    for (int r = 0; r < m.length; r++) System.out.print(m[r][c] + " ");
}
1 4 2 5 3 6 

Toplamlar, en büyük, köşegen

public static int total(int[][] m) {
    int t = 0;
    for (int[] row : m)
        for (int v : row)
            t += v;
    return t;
}
public static int[] rowSums(int[][] m) {
    int[] sums = new int[m.length];               // her satıra bir toplam
    for (int r = 0; r < m.length; r++)
        for (int c = 0; c < m[r].length; c++)
            sums[r] += m[r][c];
    return sums;
}
public static int colSum(int[][] m, int c) {
    int s = 0;
    for (int r = 0; r < m.length; r++) s += m[r][c];
    return s;
}
public static int max(int[][] m) {
    int best = m[0][0];
    for (int r = 0; r < m.length; r++)
        for (int c = 0; c < m[r].length; c++)
            if (m[r][c] > best) best = m[r][c];
    return best;
}
// main: m = {{1, 2, 3}, {4, 5, 6}}
System.out.println(total(m) + " " + Arrays.toString(rowSums(m)) + " " + colSum(m, 1) + " " + max(m));
21 [6, 15] 7 6

rowSums’ın iz tablosu, m = {{1, 2, 3}, {4, 5, 6}} için:

r   c   m[r][c]   sums
0   0   1         [1, 0]
0   1   2         [3, 0]
0   2   3         [6, 0]
1   0   4         [6, 4]
1   1   5         [6, 9]
1   2   6         [6, 15]

Satır toplamında satır sabit, sütun döner. Sütun toplamında sütun sabit, satır döner. Hangisinin sabit kaldığını düşünmek, döngüyü doğru kurmanın kısa yolu.

Köşegenler (kare dizide)

int[][] sq = {
    {2, 0, 1},
    {3, 5, 4},
    {9, 8, 6}
};
int diag = 0;
for (int i = 0; i < sq.length; i++) diag += sq[i][i];                    // ana köşegen
int anti = 0;
for (int i = 0; i < sq.length; i++) anti += sq[i][sq.length - 1 - i];    // yan köşegen
13
15

Ana köşegende (main diagonal) satır ve sütun indeksi eşit: 2 + 5 + 6. Yan köşegende toplamları n - 1: sq[0][2] + sq[1][1] + sq[2][0] = 1 + 5 + 9. Köşegen için tek döngü yeter.

Transpoze

Satırları sütun yapmak: yeni dizinin boyutları ters çevrilir, t[c][r] = m[r][c]. {{1, 2, 3}, {4, 5, 6}} için:

[[1, 4], [2, 5], [3, 6]]

Formülle doldurmak

Çarpım tablosu gibi her hücre indekslerden hesaplanıyorsa:

int[][] table = new int[3][3];
for (int r = 0; r < 3; r++)
    for (int c = 0; c < 3; c++)
        table[r][c] = (r + 1) * (c + 1);
System.out.println(Arrays.deepToString(table));
[[1, 2, 3], [2, 4, 6], [3, 6, 9]]

Dizilerin dizisi ve düzensiz diziler

int[][] m aslında her elemanı bir int[] olan bir dizidir. m’nin kendisi satırların referanslarını tutar. Bu yüzden:

  • int[] row = m[0]; ilk satırın referansını alır; row[1] = 20 doğrudan m[0][1]’i değiştirir.
  • Satırların uzunlukları farklı olabilir: düzensiz dizi (ragged / jagged array).
int[][] tri = new int[4][];              // 4 satır, sütunlar henüz yok
for (int r = 0; r < tri.length; r++) {
    tri[r] = new int[r + 1];             // r. satırda r+1 eleman
    for (int c = 0; c <= r; c++) tri[r][c] = r + c;
}
for (int[] row : tri) System.out.println(Arrays.toString(row));
int[][] jag = {{1}, {2, 3, 4}, {5, 6}};
System.out.println(jag.length + " " + jag[1].length + " " + jag[2][1]);
[0]
[1, 2]
[2, 3, 4]
[3, 4, 5, 6]
3 3 6

TUZAK · sütun sayısını sabit yazmak. jag dizisinde iç döngüyü c < 3 diye yazınca ilk (tek elemanlı) satırda ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 alındı. c < jag[0].length yazınca çökmedi ama her satırdan sadece ilk eleman toplandı: 8 (doğrusu 21). Her satır için m[r].length kullan.

Metoda 2D dizi geçirmek

1D ile aynı kural: referansın kopyası gider, metot hücreleri değiştirirse çağıran da görür. Parametre tipi int[][], dönüş tipi de int[][] olabilir (transpose gibi). Satır sayısı ve sütun sayısını parametre olarak ayrıca vermene gerek yok; length ile metodun içinde öğrenirsin.

Sık yapılan hatalar

Yanlış düşünceDoğrusu
m[r][c]’de önce sütunÖnce satır
m.length toplam hücre sayısıSatır sayısı; hücre = satır × sütun
Sütun sayısı m.lengthm[r].length (ya da dikdörtgende m[0].length)
m[2,1]m[2][1]
println iç döngünün içindeİç döngüden sonra, dış döngünün içinde
Satır toplamı için iki ayrı dizi gezinmesiTek iç içe döngü, sums[r] += m[r][c]
Köşegen için iç içe döngü gerekirTek döngü: m[i][i]
Bütün satırlar aynı uzunlukta olmak zorundaDüzensiz diziler mümkün
System.out.println(m) tabloyu basarAdres; Arrays.deepToString(m)
Transpozede yeni dizi new int[m.length][m[0].length]Boyutlar ters: [m[0].length][m.length]

Kendini test et

Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.

Soru 1kolay

What is printed?

int[][] m = {{4, 7}, {1, 9}, {3, 2}};
System.out.println(m.length + " " + m[0].length + " " + m[2][0] + " " + m[1][1]);
Cevabı göster
3 2 3 9

Üç iç süslü parantez = 3 satır, her birinde 2 eleman = 2 sütun. m[2][0]: 2. satır {3, 2}, 0. sütun → 3. m[1][1]: {1, 9}'un 1. elemanı → 9.

Soru 2kolay

What is printed?

int[][] m = new int[2][3];
m[1][2] = 8;
m[0][0] = m[1][2] / 2;
int s = 0;
for (int[] row : m) for (int v : row) s += v;
System.out.println(s);
Cevabı göster
12

Yeni 2D int dizisi sıfırlarla dolar. Sadece iki hücre değişti: 8 ve 8 / 2 = 4. Toplam 12.

Soru 3orta

What is printed?

int[][] m = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int s = 0;
for (int r = 0; r < 3; r++) s += m[r][2 - r];
System.out.println(s);
Cevabı göster
15

Yan köşegen (anti-diagonal): m[0][2] = 3, m[1][1] = 5, m[2][0] = 7. 3 + 5 + 7 = 15.

Soru 4orta

What is printed?

int[][] m = {{1, 2, 3}, {4, 5, 6}};
for (int c = 0; c < 3; c++) {
    for (int r = 0; r < 2; r++) System.out.print(m[r][c]);
    System.out.print(" ");
}
Cevabı göster
14 25 36

Dış döngü sütun, iç döngü satır: dizi sütun sütun okunur. Sütun 0: 1, 4. Sütun 1: 2, 5. Sütun 2: 3, 6. Her sütundan sonra bir boşluk.

Soru 5kolay

What is printed?

int[][] m = new int[3][3];
for (int r = 0; r < 3; r++)
    for (int c = 0; c < 3; c++)
        m[r][c] = r * 3 + c;
System.out.println(m[2][1] + " " + m[1][2]);
Cevabı göster
7 5

Formül hücreleri 0'dan 8'e satır satır numaralar. m[2][1] = 2 * 3 + 1 = 7, m[1][2] = 1 * 3 + 2 = 5.

Soru 6orta

What is printed?

int[][] m = {{5, 1}, {2, 8}, {6, 3}};
int cnt = 0;
for (int r = 0; r < m.length; r++)
    for (int c = 0; c < m[r].length; c++)
        if (m[r][c] > r * 3) cnt++;
System.out.println(cnt);
Cevabı göster
3

Eşik her satırda değişir. r = 0: eşik 0, 5 ve 1 geçer (2). r = 1: eşik 3, sadece 8 (1). r = 2: eşik 6, 6 > 6 false, 3 de değil (0). Toplam 3.

Soru 7orta

What is printed?

int[][] m = {{1}, {2, 3}, {4, 5, 6}};
int s = 0;
for (int r = 0; r < m.length; r++) s += m[r][m[r].length - 1];
System.out.println(s);
Cevabı göster
10

Düzensiz (ragged) dizi: satır uzunlukları 1, 2, 3. Her satırın son elemanı: 1, 3, 6. Toplam 10. Sütun sayısı için hep m[r].length kullan, sabit sayı değil.

Soru 8zor

What is printed?

int[][] m = {{1, 2}, {3, 4}};
int[] row0 = m[0];
row0[1] = 20;
m[1] = new int[]{7, 7, 7};
System.out.println(m[0][1] + " " + m[1].length);
Cevabı göster
20 3

2D dizi aslında dizilerden oluşan bir dizi. row0 = m[0] ilk satırın referansını alır; row0[1] = 20 m[0][1]'i değiştirir. m[1] yerine 3 elemanlı yeni bir satır konabilir; satır uzunlukları farklı olabilir.

Soru 9kolay

Using rowSums (returns an array with the sum of each row), colSum(m, c) and max(m), what is printed?

int[][] m = {{3, 1, 2}, {9, 4, 6}};
System.out.println(Arrays.toString(rowSums(m)) + " " + colSum(m, 0) + " " + max(m));
Cevabı göster
[6, 19] 12 9

Satır toplamları: 3 + 1 + 2 = 6, 9 + 4 + 6 = 19. Sütun 0: 3 + 9 = 12. En büyük eleman 9.

Soru 10kolay

How many elements does new int[3][4] contain, and what does m[2].length * m.length evaluate to?

Cevabı göster
12 elements; 12

3 satır × 4 sütun = 12 hücre. m.length satır sayısı (3), m[2].length o satırdaki sütun sayısı (4). 4 * 3 = 12.

Soru 11orta

Write a static method colSum(int[][] m, int c) that returns the sum of column c of a rectangular 2D array.

Cevabı göster
for (int r = 0; r < m.length; r++) s += m[r][c];

Sütun sabit, satır değişir: tek döngü yeter.public static int colSum(int[][] m, int c) { int s = 0; for (int r = 0; r < m.length; r++) { s += m[r][c]; } return s;}Test: {{1, 2, 3}, {4, 5, 6}} için colSum(m, 1) → 7.

Soru 12zor

Write a static method transpose(int[][] m) that returns a new array whose rows are the columns of m (m is rectangular).

Cevabı göster
int[][] t = new int[m[0].length][m.length]; ... t[c][r] = m[r][c];

Yeni dizinin boyutları ters: satır sayısı m'nin sütun sayısı, sütun sayısı m'nin satır sayısı.public static int[][] transpose(int[][] m) { int[][] t = new int[m[0].length][m.length]; for (int r = 0; r < m.length; r++) for (int c = 0; c < m[0].length; c++) t[c][r] = m[r][c]; return t;}Test: {{1, 2, 3}, {4, 5, 6}} → [[1, 4], [2, 5], [3, 6]]. {{1, 2}, {3, 4}} → t[0][1] = 3, t[1][0] = 2.

Doğrulama: Tüm çıktılar JDK 26 ile çalıştırıldı (verify/SEN1001/W09.java ve W09b.java). printf hizalamasındaki boşluklar cat -A ile kontrol edildi.

Deftere not kartı

int[][] m = new int[satır][sütun]; int[][] m = {{1,2,3},{4,5,6}}; m[r][c] → önce satır, sonra sütun m.length = satır sayısı m[r].length = r. satırın sütun sayısı Varsayılan değerler 1D ile aynı: 0, 0.0, false, null Gezinme: for (r = 0; r < m.length; r++) for (c = 0; c < m[r].length; c++) Satır satır yazdır: iç döngüden sonra println() Enhanced: for (int[] row : m) for (int v : row) Satır toplamı: r sabit, c döner Sütun toplamı: c sabit, r döner Ana köşegen m[i][i] yan köşegen m[i][n-1-i] (kare dizide) Transpoze: t = new int[m[0].length][m.length]; t[c][r] = m[r][c]; m[r] bir 1D dizi (referans): int[] row = m[0]; row[1] = 5 → m[0][1] değişir Düzensiz: int[][] t = new int[4][]; t[r] = new int[r+1]; println(m) adres basar Arrays.deepToString(m) → [[1, 2], [3, 4]] Toplam hücre (dikdörtgen): satır × sütun