“C# – Koleksiyonlar” başlıklı yazımızda koleksiyonların avantajlarından, dezavantajlarından bahsedip, genel bir bilgi vermiştik. Bu yazımızda ise bir koleksiyon sınıfı olan Stack‘den bahsedeceğiz.
Stack Sınıfının Temel Yapısı
Stack, ilk giren son çıkar işleyişine sahip bir koleksiyondur. Diğer bir deyişle; ilk eklenen elemanın koleksiyondan en son çıkarıldığı ve en son eklenen elemanında ilk çıkarıldığı bir veri yapısıdır (LIFO).
Stack tıpkı diğer koleksiyon sınıfları gibi dinamik bir yapıya sahiptir. Yani eleman eklendikçe boyutu dinamik olarak artmaktadır.
Stack sınıfının Pop() ve Push() olmak üzere 2 temel metodu bulunmaktadır.
- Pop(): Stack’in en üstündeki nesneyi çıkarır.
- Push(): Stack’in en üstüne bir nesne ekler.
Metotlara daha sonra detaylı bir şekilde değineceğiz. Bu kısımda dikkatinizi çekmek istediğim husus; Ekleme ve çıkarma işleminin yalnızca stack’in tepe noktasından yapılmasıdır.
Stack’in Kullanım Yerleri
Tarayıcılarda bulunan “Geri“ butonu, en son ziyaret edilen sayfaya dönme işlemini stack veri yapısını kullanarak gerçekleştirmektedir. Ziyaret edilen siteler Stack’e atılıp, her “Geri“ butonuna tıklanıldığında Stack’in tepesinde bulunan site, Stack’ten çıkarılıp (POP), tarayıcının adres çubuğuna gönderilerek, bir önceki web sitenin görüntülenmesi sağlanır.
Aynı şekilde word, notepad++ gibi editörlerde bulunan “Geri Al“ butonu, en son yaptığımız işlemin geri alınmasını yine Stack veri yapısını kullanarak gerçekleştirmektedir.
Program yazarken, bir fonksiyonun içerisinde, başka bir fonksiyonu çağırdığımızda; En son çağrılan fonksiyon tamamlandıktan sonra kendisinin çağrıldığı fonksiyonda; çağrıldığı satıra dönebilmesi için o yerin adresini Stack’te tutmaktadır.
Verilen örnekler haricinde daha bir çok kullanım alanı sıralanabilir.
Metotlar ve Özellikler
- Nesne Oluşturma
Stack sınıfından bir nesne oluşturuyoruz. Bu nesne, koleksiyondaki nesnelerin referanslarını tutacaktır.// Stack içerisine sadece belirtilen veri tipindeki öğeler eklenebilir. // Eleman ekleme ve çıkarma işlemlerinde Boxing-Unboxing gerçekleşmez. Stack<int> yigin = new Stack<int>(); // Stack içerisine veri tipi fark etmeksizin her türlü öğe eklenebilir. // Eleman ekleme ve çıkarma işlemlerinde Boxing-Unboxing gerçekleşir. Stack yigin = new Stack();
- Push(Eklenecek_Oge) ve Pop() Metotları
Push() Metodu; Parametre olarak girilen öğeyi Stack’in tepe noktasına eklemektedir. Pop() Metodu; Stack’in tepe noktasındaki öğeyi döndürür ve sonra öğe Stack’ten çıkarılır/silinir. Stack boşken Pop() metodu çağrılırsa InvalidOperationException fırlatır.Stack<string> yigin = new Stack<string>(); yigin.Push("www.google.com"); yigin.Push("www.srdrylmz.com"); // Ekran çıktısı: www.srdrylmz.com // "www.srdrylmz.com" öğesi silinir. try { string site = yigin.Pop(); Console.WriteLine(site); } catch (InvalidOperationException) { Console.WriteLine("Stack Boş."); }
- Peek() Metodu
Stack’in tepe noktasındaki öğeyi döndürmektedir, Pop() metodunda farklı olarak öğeyi Stack’ten çıkarmaz/silmez. Stack boşken Peek() metodu çağrılırsa InvalidOperationException fırlatır.Stack<string> yigin = new Stack<string>(); yigin.Push("www.google.com"); yigin.Push("www.srdrylmz.com"); // Ekran çıktısı: www.srdrylmz.com // "www.srdrylmz.com" öğesi silinmez. try { string site = yigin.Peek(); Console.WriteLine(site); } catch (InvalidOperationException) { Console.WriteLine("Stack Boş."); }
- Contains(Aranan_Öğe) Metodu
Stack içerisinde parametre olarak girilen öğeyi arar. Öğe bulunursa TRUE, bulanamazsa FALSE döndürür.Stack<string> yigin = new Stack<string>(); yigin.Push("www.google.com"); yigin.Push("www.srdrylmz.com"); // Ekran Çıktısı: Mevcut Değil. if (yigin.Contains("www.sakarya.edu.tr")) Console.WriteLine("Mevcut."); else Console.WriteLine("Mevcut Değil.");
- ToArray() Metodu
Stack’te yer alan elemanların kopyasını içeren bir dizi döndürür.Stack<string> yigin = new Stack<string>(); yigin.Push("www.google.com"); yigin.Push("www.srdrylmz.com"); string[] Dizi = yigin.ToArray(); /* Ekran Çıktısı:www.srdrylmz.com www.google.com */ for (int i = 0; i < Dizi.Length; i++) Console.WriteLine(Dizi[i]);
- Clear() Metodu ve Count Özelliği
Clear() Metodu; Stack’i temizlemektedir. Count Özelliği; Stack içerisinde yer alan elemanların sayısını döndürmektedir.Stack<string> yigin = new Stack<string>(); yigin.Push("www.google.com"); yigin.Push("www.srdrylmz.com"); // Ekrana "2" yazacaktır. Console.WriteLine(yigin.Count); yigin.Clear(); // Ekrana "0" yazacaktır. Console.WriteLine(yigin.Count);
Uygulama
- Öğeleri Listeleme
Stack’te bulunan öğeler foreach döngüsüyle görüntülenebilir.string[] Dizi = { "Microsoft", ".NET", "Framework" }; // Dizi içerisindeki öğeler sırayla Stack'e aktarıldı. Stack<string> yigin = new Stack<string>(Dizi); // Stack içerisindeki öğeler sırayla ekrana yazdırıldı. // Ekran Çıktısı: Framework .NET Microsoft foreach (string oge in yigin) Console.Write(oge + " ");
- Parantez Kontrolü
Bir Aritmetik ifadede açılan her bir parantez kapatılmalıdır. Yani Sol parantez adedince, sağ parantez olmalıdır. Aşağıdaki uygulamamız Stack kullanarak parantez kontrolü yapmaktadır.
ALGORİTMA
• Okunan her bir sol parantez Stack’e eklenir.
• Okunan her bir sağ parantez için de Stack’den bir sol parantez çıkarılır.
• Stack boşken bir sağ parantez okunması yani Stack’ten eleman çıkarılmaya çalışılması; aritmetik ifadede açılmamış bir parantezin kapatılmaya çalışıldığı yani fazladan bir sağ parantez bulunduğu anlamına gelir. Bu durumda aritmetik ifade hatalıdır.
• Tüm aritmetik ifade tarandıktan sonra Stack’te eleman kalmamışsa, açılan her bir parantez kapatılmıştır. Bu durumda aritmetik ifadede herhangi bir parantez hatası bulunmamaktadır. Aksi durumda Stack’te açılan bir parantez kapatılmamış olacağı için Aritmetik ifade hatalı olacaktır.private static bool ParantezKontrol(string Aritmetik) { Stack<string> yigin = new Stack<string>(); for (int i = 0; i < Aritmetik.Length; i++) { if (Aritmetik[i] == '(') { // Okunan her bir sol parantez Stack'e eklenir. yigin.Push("("); } else if (Aritmetik[i] == ')') { try { // Okunan her bir sağ parantez için Stack'den bir sol parantez çıkarılır. yigin.Pop(); } catch (InvalidOperationException) { // Aritmetik ifadede açılmamış bir parantez kapatılmaya çalışılmış. return false; } } } if (yigin.Count != 0) // Açılan bir parantez kapatılmamış. return false; else // Açılan her bir parantez kapatılmış. return true; } static void Main(string[] args) { string Aritmetik1 = "(1+2)+(4*8)+9"; // Parantez kullanımı doğru. string Aritmetik2 = "(1+2))+(4*8)+9"; // Açılmamış bir parantez kapatılmaya çalışılmış. string Aritmetik3 = "((1+2)+(4*8)+9"; // Açılan bir parantez kapatılmamış. string Aritmetik4 = "(((((((()))))))))"; // Açılmamış bir parantez kapatılmaya çalışılmış. Console.WriteLine(ParantezKontrol(Aritmetik1)); // TRUE Console.WriteLine(ParantezKontrol(Aritmetik2)); // FALSE Console.WriteLine(ParantezKontrol(Aritmetik3)); // FALSE Console.WriteLine(ParantezKontrol(Aritmetik4)); // FALSE }
Serdar Yılmaz
Hocam yarın finalim var. İşin tuhafı benim de erzurumda doğup Sakarya Üniversitesinde Bilgisayar Mühendisliiği okumam. Elinize sağlık güzel bir bilgilendirici yazı olmuş
anlatım için teşekkürler. bu arada siteye koyu tema ekleseniz süper olacak 😀
Merhaba,
Çok sadece bir anlatımınız var. Tebrikler. Parantez sorusuna benim de naçizane 2 tane çözümüm var. Belki okuyan birilerinin işine yarar 🙂
private static bool paranthesesMatch(string expression)
{
Stack paranthases = new();
foreach (char item in expression)
{
if (item == ‘(‘)
{
paranthases.Push(item);
}
else if (item == ‘)’)
{
if (!paranthases.TryPop(out _))
{
return false;
}
}
}
return paranthases.Count == 0;
}
private static bool paranthesesMatch2(string expression)
{
Dictionary charStore = new();
foreach (char item in expression)
{
charStore[item] = charStore.TryGetValue(item,out int value) ? value + 1 : 1;
}
return charStore[‘(‘] == charStore[‘)’];
}
Hocam teşekkürler, güzel anlatmışsınız
hocam bu örnekler için çok teşekkürler .
okul dersten pek bir şey anlamamıştım sizin sayenizde bir şeyler öğrendim .
iyi günler .