Memoization

Latince memorandum kelimesinden türeyen memoization, birden çok defa hesaplanması gereken işlemlerin sonucunun hatırlanıp, aynı işlemi tekrar tekrar yapmamıza engel olan ve bu şekilde zamandan kazanmamızı sağlayan optimizasyon tekniğidir. Klasik örnek olacak belki ama fibonacci örneğini ele alalım.

Normalde yazdığımız fibonacci sayısı hesaplayan özyinelemeli fonksiyon

int fibonacci(int n) { if (n == 1 || n == 2) return 1; else return fibonacci(n – 1) + fibonacci(n – 2); }

Yukarıdaki fonksiyonun fibonacci(5) şeklinde çağırılmasından sonra sonucu bulması için gerçekleşecek özyinelemeli çağrılar sonucunda oluşacak ağaç şu şekildedir:

[![](http://www.onurbaysan.com/blog/wp-content/uploads/2011/11/tree.png “tree”)](http://www.onurbaysan.com/blog/wp-content/uploads/2011/11/tree.png)

 

 

Bu şekilde görüldüğü gibi 3 değeri 2 kez çalıştırılacak. Bu fonksiyonun 5 ile değil de daha büyük bir sayı ile çağırıldığı düşünülecek olursa tekrar hesaplanacak değerlerin sayısı artacaktır.

Ama eğer biz her hesaplanan fibonacci sayısının değerini bir veri yapısında tutacak olursak ve aynı işlemi tekrarlamamız gereken durumda direk sonucuna erişim yapabiliriz. Bunu da şu şekilde bir kod ile yapabiliriz.

 

//Memoization işleminde kullanılacak veri yapısı Dictionary fibs = new Dictionary(); int mFibonacci(int n) { if (n == 1 || n == 2) return 1; if (fibs.ContainsKey(n)) return fibs[n]; else { fibs[n] = mFibonacci(n – 1) + mFibonacci(n – 2); return fibs[n]; } }

 

Yukarıdaki verilen 2 farklı koda ait çalışma zamanları bilgileri aşağıda mevcuttur.

[![](http://www.onurbaysan.com/blog/wp-content/uploads/2011/11/output-1024×324.png “output”)](http://www.onurbaysan.com/blog/wp-content/uploads/2011/11/output.png)

Son söz olarak bu yöntem ile zamandan kazanmamıza rağmen sizin de farketmiş olacağınız üzere ek bellek kullandığımız için yerden kaybediyoruz.

305 Words

C#’ta XML Serialization ve Deserialization

Kısaca serileştirmeyi tanımlayacak olursak; serileştirme , elimizdeki mevcut nesne(ler)i istenilen formata getirmeye yarıyor diyebiliriz. Bunlardan en bilinenleri XML Serileştirme , JSON Serileştirme , Binary Serileştirme. (Kendinize yeni bir format geliştirirseniz o şekilde de serileştirebilirsiniz.)

Herneyse konumuza dönecek olursak XML DOM’daki gibi tek tek appendNode , insertElement tarzındaki methodları kullanmadan nesnelerimizi direk olarak nasıl XML formatına dönüştürürüz daha doğrusu bu işi C#’ta basit olarak nasıl yaparız ondan bahsedeceğim. (Not: Java’da benzer işlemi yapmak istiyorsanız JAXB sizin için yararlı olacaktır.)

Öncelikle serileştirmek istediğim nesnelerin türetileceği sınıfı yazıyorum. Kişilere ait belirli nitelikleri tutan Person adında bir sınıfım var.

public class Person { public string name { get; set; } public string cell_phone { get; set; } public string hometown { get; set; } }

Şimdi ise elimde bulunan birden çok kişi nesnesini bir listede tutacağım ve bu listeyi nasıl serileştireceğimizi göstereceğim. İlk olarak listemizin tanımını yapıp , kişileri bu listeye ekliyorum.

 

Sıra geldi serileştirme işlemini yapan kod kesimini yazmaya. Bunun için System.Xml.Serialization namespace’inden yararlanacağız ve bu namespace te yer alan XmlSerializer sınıfını kullanacağız.

Nesnelerimiz belirttiğimiz adreste bulunan XML dosyasına yazılmış bulunuyor.

[![](http://www.onurbaysan.com/blog/wp-content/uploads/2011/08/serial-300×153.png “serial”)](http://www.onurbaysan.com/blog/wp-content/uploads/2011/08/serial.png)

Şimdi de bu işlemin tam tersini yani mevcut XML’den nesne elde etme işlemi de benzer şekilde birkaç satır kod ile yapılabiliyor.

 

359 Words

C#’ta Reflection – 2

Geçen yazımda Reflection’a dair temel bilgileri ve ismini bilmediğimiz bir metodu nasıl çağıracağımızı öğrenmiştik. Bu yazımda ise C#’ta yazılmış bir DLL dosyasının içindeki sınıflara nasıl erişiriz , bu sınıflardan nasıl nesneler oluşturabiliriz onlardan bahsedeceğim. (Tabi ki tüm bunlar çalışma zamanında olacak)

Bu DLL dosyası içinde bulunan sınıfın constructor ına  erişerek nesne yaratmam için aşağıdaki kodu kullanıyoruz.

//DLL dosyasının yüklenmesi Assembly asm = Assembly.LoadFile(@”C:\Ornek.dll”); object obj; //DLL dosyası içindeki sınıf bilgilerinin elde edilmesi foreach (Type type in asm.GetTypes()) { //Sınıflara ait constructor bilgilerinin elde edilmesi foreach (ConstructorInfo cInfo in type.GetConstructors()) { // Constructor ın aldığı parametre tipine göre // o tipten parametre kullanılarak nesne // yaratılması if (cInfo.GetParameters()[0].ParameterType == Type.GetType(“System.Int32”)) { obj = Activator.CreateInstance(type, 3); } else if (cInfo.GetParameters()[0].ParameterType == Type.GetType(“System.String”)) { obj = Activator.CreateInstance(type, “deneme”); } } }

* Dipnot=  Bu kodu yazarken varsayım olarak constructor’ın tek bir parametre aldığını varsaydık ve bu aldığı parametrenin tipi *Int32* veya *String* ise nesnenin yaratılmasını istedik.

207 Words

C#’ta Reflection

Program yazarken çoğu zaman Ctrl+Space kombinasyonu ile kullandığımız methodların dönüş değerlerine, aldıkları parametrelere , parametrelerin tipine vs gibi özelliklerine bakarız. Çoğu IDE sayesinde bunlara da erişmiş oluruz. Bu noktada birkaç senaryo üzerinden devam edelim.

1. Senaryo ) Bir sınıfın içindeki methodlara ait bilgilerin edinilmesi. (klasik senaryo)
2. Senaryo ) Başka birisinin yazmış olduğu bir sınıf var. Normal koşullarda o kod dosyasını açmadan “private”  , “protected” tipinde olan methodların , niteliklerin isimlerini öğrenemezsiniz. Bu durumda da yardıma koşuyor.
3. Senaryo ) Basit olarak JavaDOC benzeri bir aracı C# için yazmak istediniz. Burada da yorum methodlardan , niteliklerden önce yorum satırlarını okuyup onlara ayrıştırmak yerine Reflection sayesinde basit olarak buna benzer bir araç geliştirebilirsiniz.
*** 4. Senaryo ) Bayağı bir zamandır merak ettiğim ve yeni öğrendiğim birşey. İsmini bilmediğimiz bir methodun ismini çalışma zamanında öğrendik fakat biz bu methodu çalışma zamanında çağırabilir miyiz? Yani demek istediğim yaz() diye bir method var ve biz bu methodun ismini kodu yazarken bilmiyoruz ama çalışma zamanında çağırmak istiyoruz.

Bu kadar senaryodan sonra basit olarak ismini bildiğimiz bir sınıfın methodlarına ait bilgileri nasıl ediniriz diyerek kod kısmına geçelim.

Type intType = Type.GetType(“System.Int32”); foreach (MethodInfo mInfo in intType.GetMethods()) { Console.WriteLine(“————————————“); //Methodun ismi Console.WriteLine(mInfo .Name + ” “); int counter = 0; foreach (ParameterInfo pInfo in mInfo .GetParameters()) { //Methodun aldığı parametrelerin tipleri Console.WriteLine(counter + “. param tipi= ” + pInfo.ParameterType + ” “); counter++; } //Donus değerinin tipi Console.WriteLine(mInfo .ReturnType); Console.WriteLine(“————————————“); }

Yukarıdaki kod ile erişim belirleyicisi(access modifier) ne olursa olsun tüm methodlara dair bilgileri edinmek istersek GetParameters() methoduna parametre olarak BindingFlags’ler vermemiz gerekir. “BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static” şeklinde parametre verirsek tüm methodlara ait bilgilere erişebiliriz.

Geldik bana göre en can alıcı kısma. Şimdi de ismini çalışma zamanında öğrendiğimiz bir methodun yine çalışma zamanında nasıl çağrılacağını gösteren basit bir kod parçasını inceleyelim. Bu kod parçasında sınıfın ilk methodunu çağırıyorum. Buna göre kodun çıktı olarak “deneme123” vermesi gerekiyor. Gerçekten de kodu çalıştırdığımız zaman beklediğimiz sonucu ekranda görüyoruz.

class Boxer { public void test() { Console.WriteLine(“deneme123”); } }

Type unknownBoxer = typeof(Boxer); unknownBoxer.GetMethods()[0].Invoke(new Boxer() , null);

418 Words

Bir Metottan Birden Çok Parametre Döndürme

Programlama dillerinde bir fonksiyondan hepimizin bildiği üzere sadece bir parametre döndürebiliriz. Buradaki döndürmekten kasıt yapılan “*return*” işlemiyle sadece bir parametre döndürdüğümüzdür. Peki eğer birden çok parametre döndürmek istersek ne yaparız? Bunun için 3 methodtan bahsedeceğim.

C’ye alışkın insanların bu soruya vereceği cevap “struct” kullanırız olacaktır. Struct tanımı içinde kullanmak istediğimiz parametreleri belirtir fonksiyonun dönüş tipini de tanımladığımız Struct türünden yaparsak bu işi başarıyla gerçekleştiririz.  OOP’de bunu sınıflar aracılığıyla yaparız.

1. Method:

class Program { static void Main(string[] args) {      Parameters x = foo(); Console.WriteLine(x.a + ” – ” + x.b); Console.ReadKey(); /* Konsolun işlemden sonra herhangi bir tuşa basılana kadar açık kalmasını sağlamak için */ } static Parameters foo() {      Parameters param = new Parameters(); param.a = 5; param.b = 8; return param; } } class Parameters { public int a, b; }

2. Method: Bu methodumuzda “out” parametresini kullanmak olacaktır.

static void Main(string[] args) { int x, y; x = foo(out y); Console.WriteLine(x + ” – ” + y); Console.ReadKey(); /* Konsolun işlemden sonra herhangi bir tuşa basılana kadar açık kalmasını sağlamak için */ } static int foo(out int var1) { var1 = 5; return 8; }

3. Method: .Net Framework 4.0 ile gelen [Tupples](http://msdn.microsoft.com/en-us/library/system.tuple.aspx)

static void Main(string[] args) {    var result = foo(); Console.WriteLine(result.Item1 + ” – ” + result.Item2);    Console.ReadKey(); /* Konsolun işlemden sonra herhangi bir tuşa basılana kadar açık kalmasını sağlamak için */ } static Tuple foo() { return Tuple.Create(3 , “uccccc”); }

Son örnek hariç diğer örnekler hep aynı türden veriler kullanmışım fakat önceki örneklerde de farklı türden veriler kullanmamız mümkün. Ayrıca aynı türe sahip veriler için kullanılacak başka methodlarda mevcut. Mesela *Collections *kullanımı.

İyi akşamlar

333 Words