Çok boyutlu diziler (MultiDimensional Arrays)

Yazan : Şadi Evren ŞEKER

Bilgisayar bilimlerindeki pek çok programlama dilinde birden fazla boyuttan oluşan dizilerin kullanılması mümkündür.

Örneğin bir ders çizelgesini, haftalık yemek listesini yada kişilerin aylık satışlarından oluşan bir tabloyu ele alalım. Günlük hayatta pek çok yerde tablolar kullanılmaktadır. Aynı zamanda matrisler (masfuf, matrix) matematikte küçümsenmeyecek bir öneme sahiptir.

İçerik
1. Çok boyutlu dizilerin tanımlanması
2. Çok boyutlu dizilerin kullanılması
3. İkiden çok boyutlu diziler

Tutulan bilgi her ne olursa olsun şayet tablo gibi iki boyutlu bir bilgiyse ya da daha fazla boyutu varsa bu bilginin tek boyutlu dizilerle modellenmesi ve işlenmesi güçtür.

Bunun yerine programlama dillerinde birden fazla boyuttan oluşan diziler (array) kullanılabilir. Bu dizilere çok boyutlu dizi (multi dimensional array) ismi verilir.

Çok boyutlu dizilerin tanımlanması

Günümüzde oldukça yaygın olan C yazım kurallarına göre ( C-syntax) bir matris aşağıdaki şekilde tanımlanabilir:

int a[3][3];

Yukarıdaki bu satırı, C/C++ programlama dilinde yazarsak hafızada bizim için 3×3 boyutlarında (3’e 3’lük) bir matris için yer açar (yani toplamda 9 hücreli ve 9 farklı sayı tutmaya yarayan bir yer) ve bu matrisin ismini a olarak tanımlar. Buradaki a matrisin (yani iki boyutlu dizinin (array)) ismidir ve herhangi bir değişken ismi verilebilir. Örnek olarak a ismi kullanılmıştır.

Yukarıdaki tanım satırını JAVA veya C# dillerinde aşağıdaki şekilde yapabiliriz:

int [][] a = new int[3][3];

Yukarıdaki bu yazımda farklı olan sadece yazılış şeklidir aslında yapılan iş aynıdır.

Yukarıdaki şekilde dizi tanımlandıktan sonra bu dizinin istenilen satır ve sütün değerlerine erişilebilir. Bu durumu aşağıdaki temsili resimden görebiliriz:

a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
a[2][0] a[2][1] a[2][2]

Yukarıdaki resimde ilgili satır ve sütünlara erişmek için yazılması gereken indis değerleri verilmiştir. Yani örneğin aşağıdaki şekilde bir kod yazarsak:

a[1][2]=5;

Bu kod satırı ile a dizisinin 1. satırının 2. sütünuna 5 değeri konulmuş olur:

0 0 0
0 0 5
0 0 0

Burada önemli bir uyarı yapmak gerekir. Yukarıdaki satır ve sütün bilgileri tamamen bir kabule dayalıdır. Yani matrisin ilk indisi satır ikinci indisi sütün olarak gösterilmiş ve kullanılmıştır. Oysaki bilgisayarın hafızasında (RAM, Memory) tek boyutlu bir yapı vardır ve bizim iki boyutlu yapılarımız tek boyuta indirilerek tutulur. Dolayısıyla bizim satır ve sütün tutan indislerimiz bir kabule dayanır. Yani aslında aşağıdaki şekilde bir göterim de pek âlâ doğrudur:

a[0][0] a[1][0] a[2][0]
a[0][1] a[1][1] a[2][1]
a[0][2] a[1][2] a[2][2]

Yukarıdaki her iki göterimde bir kabule dayanır (aslında hafızada tek boyutlu olan bilginin iki boyutlu gösterilmesi bir kabuldür) ve programcı hangi kabulü isterse yapabilir ancak birisini kabul ederek bütün programcılık hayatı boyunca bu kabul üzerine devam edebilir.

Ancak programlama dili yazan arkadaşların (derleyiciler teorisi (compiler theory) gibi konular ile ilgilenen kişilerin) bu detayı bilmesinde yarar olabilir. Bu yüzden dilerlerse satır bazlı sıra (row major order) ve sütün bazlı sıra (column major order) başlıklı yazıları okuyabilirler.

Çok boyutlu dizilerin kullanılması

Çok boyutlu diziler genelde döngüler (loop) ile birlikte kullanılırlar. Bilindiği üzere aslında dizi (array) kavramının varlık sebebi birden fazla değişkeni hafızada bir arada tutmak ve kolayca ulaşmaktır. Dolayısıyla birden fazla değişkene erişirken indis numaralarından (satır ve sütün numaralarından) erişmek çoğu zaman avantajlı bir durumdur. İşte bu satır ve sütün numaraları üzerinde çalışan döngüler de çoğu zaman vaz geçilmez erişim araçlarıdır.

Örneğin aşağıdaki kodu ele alalım:

int a[5][5]; //diziyi tanimladik
//içine değer atıyoruz
for(int i = 0;i<5;i++){
   for(int i = 0;i<5;i++){
      a[i][j]=i+j;
   }
}
//değerleri bastırıyoruz
for(int i = 0;i<5;i++){
   for(int i = 0;i<5;i++){
      printf("%d ",a[i][j]);
   }
   printf("n");
}

Yukarıdaki kodun çıktısı aşağıdaki şekildedir:

0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

Görüldüğü üzere yukarıdaki kod ile 5×5 boyularında bir matris tanımlanmış ve bu matrisin içerisine 01234 değerlerinden oluşan satır her seferinde 1 arttırılarak tekrarlanmıştır.

Yukarıda bu işlemi yapmaya yarayan kod değerlerin atandığı ve bastırıldığı iki bölüm olarak düşünülebilir ve her iki bölümde de dizinin elemanlarına döngüler marifeti ile erişilmiştir.

İkiden çok boyutlu diziler

Şimdiye kadar anlatılan diziler iki boyutluydu. Programlama dillerinde ikiden yüksek sayıdaki boyutlarda dizi tanımlamak da mümkündür. Temel olarak programlama dillerinin çoğunda matrisin boyutunun bir limiti yoktur yani 3 boyutlu 4 boyutlu yada 100 boyutlu diziler tanımlanabilir.

Aslında dizi tanımı sırasında tek limit bilgisayarın donanım ve işletim sistemi kaynaklarından doğar. Yani örneğin bir tam sayı değerinin (int) 2 bayt (byte) kapladığı bir işletim sisteminde 10000x10000x10000 boyutlarına sahip 3 boyutlu bir dizi tanımlanırsa ( 104 104 104 = 1012 x 2 byte = 2×1012 byte ~ 1 terabyte) yaklaşık olarak 1TB yapar ki bu günümüz bilgisayarları için oldukça yüksek bir RAM miktarıdır.

Programlama dillerinde çok boyutlu diziler iki boyutlu dizilerde olduğu gibi boyut miktarını belirten ilave sayılar tanımlayarak gösterilir. Örneğin:

int a[5][5][5];

şeklindeki bir tanım C/C++ dillerinde veya

int [][][] a = new int[5][5][5];

şeklindeki bir tanım JAVA vey C# dillerinde 5x5x5 boyutlarında 3 boyutlu bir dizi tanımlamak için kullanılabilir.

Burdaki boyut sayısında bir limit bulunmamaktadır. Örneğin

int a[5][5][5][5][5];

şeklindeki bir satır ile 5 boyutlu (ve her boyutu 5 olan) bir dizi tanımlanabilir.

Yorumlar

  1. t0xic

    içiçe döngülerde 2.for döngüsünde değişken j olmalı sanırım yanlış yazılmıs zira bu şekilde programın çıktısı daha farklı oluyor.

  2. murat uçan

    iyi günler hocam
    C++ bilder da çok boyutlu ve boyutu belli olmayan dizi nasıl tanımlanır ? örneğin kullanıcının girdiği sayılar dizinin boyutu olacak .. consol daki tanımlama protatiflerini uygulayınca hata veriyor. builder da çok boyutlu dizi tanımlamanın özel bi yöntemi mi var ?

    http://www.muratucan.com

  3. Şadi Evren ŞEKER Article Author

    Her gösterici (pointer) yapı olarak bir dinamik boyutlu dizidir. Aşağıdaki yazıya bir göz atmanızda yarar var:

    http://www.bilgisayarkavramlari.com/2007/10/16/pointer-gosterici-2/

    Kısaca sizin sorunuz için aşağıdaki gibi bir kod işinizi görmeli:

    int a,b;
    cin >> a;
    cin >> b;
    int **dizi = (int **) malloc (sizeof(int)*a);
    for(int i = 0;i
    

    Yukarıdaki kod, kodlama aşamasında boyutu bilinmeyen, yani örneğin kullanıcıdan okunan boyutlarda (a x b boyutlarında) "dizi" isminda bir dizi oluşturur. kısaca dizi[a][b] şeklinde düşünebilirsiniz. Burada kullanılan yönteme literatürde göstericiler göstericisi (pointer of pointers) ismi de verilmektedir.

    başarılar

  4. tuba

    C#’da 3D matris kullanarak aşağıdaki şekli elde etmeye çalışıyorum;

    *
    *
    * * *
    * * * *
    * * * * * *
    0-9 10-19 20-29 30-39 40-49 50-59 60-69 70-79 80-89 90-100

    şimdilik kod aşağıdaki gibi fakat aralıkların olduğu kısım row 0’dan başlıyor ben 9dan başlamasını istiyorum problem nerede olabilir?

    string[, ,] number = new string[10, 10, 1];

    for (int i = 0; i < number.GetLength(0); i++) { for (int j = 0; j

  5. tuba

    Tablo yanlış çıkmış mesela 0-9’un üzerine 3 tane yıldız diğer aralıkların üzerinde de farklı sayıda yıldızlar var..

  6. Şadi Evren ŞEKER Article Author

    neden 3 boyutlu dizi tutuyorsunuz? tek boyut yeterli değil mi?

    for(int i = 0;i<10;i++){
      Console.Write(""+(i*10)+"-"+(i*10+9));
      for(int j=0;j< number[i];j++)
        Console.Write("*");
      }
      Console.Write("n");
    }
    

    Yukarıdaki kodda, her dizi elemanında kaç yıldız basılacağının tutulduğunu kabul edersek, içerdeki döngü bu sayı kadar * sembolü koyar. Kodda bulunan ilk console.write komutu ise istediğiniz satır başlıklarını basar.
    Sorunuzu tam yazmammış sadece kod vermişsiniz, bu yüzden kodunuzdan anladığım kadarıyla cevaplamaya çalıştım ama istediğiniz farklı birşeyse biraz daha anlatın lütfen.

    başarılar

  7. berfu

    Write simple standalone Java methods called by the Main method
    that takes a 2xD array of Strings, defined in the program, and outputs the followings:

    -> The even numbered (both indexes) elements of the array
    yardımcı olurmusunzz???

  8. Ozan

    merhabalar hocam dizgi sorusunu anladım ve sadece baş eleman değil artık istediğim kosulu vererek arama yaptırabiliyorum.
    hocam dolaylı olarak dizilerle ilgili bir soruda bir yerle ilgili bir sey sormak istiyorum.soruyu cok rahatlıkla yaptım ama ogrenmek istedıım bir şey var ve açıklarsanız sevinirim.
    simdi soru diyoki 10 luk tabandaki bir sayiyi 2 lik tabana donustur.onu buldum:

    #include 
    #include 
    int ikilik(int);
    int main(){
       int sayi;
       printf("sayiyi giriniz:");
       scanf("%d",&sayi);
       ikilik(sayi);
       getch();
       return 0;
    }
    int ikilik(int x){
       int index=0;
       int dizi[index];
       while(sayi>=1){
          sayi/=2;
          index++;
          dizi[index]=sayi%2;
       }
       for(index=index;index>0;index--){
          printf("%d",dizi[index]");
       }
    }
    

    hocam sımdı burda sayı orneğin 5 basamaklı olsun sımdı sız daha iyi bilirsiniz 2 hali yaklasık 16-18 arası bir hane tutuyor ve ben burada for dongusunde oynama yaparak(örneğin for(index=index-5;index>4;index–) buradan belli bir parcasını alabilirim .hocam sımdı problem su:2 likten 10’luğa da cevirmeyi biliyorum ama bu ıste dizi içindeki ayırdığım parcayı nasıl normal bir 10 luk sayiyia cevirebilirim.yani dizi içinde ya hani o kısım dizi içindeyken normal 10’luk nasıl yapıcam.Bunu bir gosterebilirseniz sevirinim hocam.

  9. Ozan

    hocam merhabalar örneğin bir dizi elemanları soyle olsun 4 6 7 4 12 11 11 9 sımdı burada dıyorkı ilk tekrarlanan sayiyi bul burada tabi 4 oluo mesela bunu nasıl yapabilirim bir turlu bulamadım hocam o ilk

  10. Şadi Evren ŞEKER Article Author

    Kodunu aşağıdaki şekilde yazabilirsiniz:

    int a[8] = {4,6,7,4,12,11,11,9};
    for(int i = 1;i<8;i++){
        for(int j = 0;j
    

    Koddan anlaşılacağı üzere bir döngü, sırasıyla ilk elemandan başlayarak bütün elemanların ikinci bir tekrarının dizide daha önce bulunup bulunmadığını kontrol etmektedir. Şayet kendisinden önce bu eleman geçiyorsa ilk tekrarlanan sayı olarak basılır.
    Kodun yazıldığı konuma göre döngülerin sonlandırılması için farklı yöntemler kullanılabilir ancak ben basit olması için dış döngüyü bitiren koşulu yazıp break yapmayı tercih ettim.

  11. BURAK KILINÇ

    hocam iyi günler benim sorum 1000×1000 lik bir diziyi threadler kullanarak kısa sürede yapmak ama ben thread işine girmeden önce şunu sormak istiyorum:1000×1000 lik büyük bir dizide stackoverflow hatası veriyor iki boyutlu büyük dizilerde dinamik bellek oluşumunu nasıl yapıcaz hocam.C++ içi yazarsanız çok sevinirim…

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir