Dizi | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar dizi

C# SortedSet sınıfı

31 October 2010 1 yorum

SortedSet sınıfı, .Net Framework 4.0 ile birlikte gelen en yeni sınıflardan biridir ve listesine eklenen elemanları sıralı bir şekilde tutar.

Bir örnek ile göstermek gerekirse;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<string>();

	SiraliListe.Add("Engin");
	SiraliListe.Add("Ahmet");
	SiraliListe.Add("Mehmet");
	SiraliListe.Add("Ayşe");
	SiraliListe.Add("Fatma");

	foreach (string s in SiraliListe)
	{
		Console.WriteLine(s);
	}

	Console.ReadLine();
}

kodunun çıktısı aşağıdaki gibi olacaktır;

Ahmet
Ayşe
Engin
Fatma
Mehmet
public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	foreach (int Sayi in SiraliListe)
	{
		Console.WriteLine(Sayi);
	}

	Console.ReadLine();
}
Çıktı : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Tüm koleksiyonlara uygulayabildiğimiz Reverse() methodu SortedSet sınıfında da kullanılabiliyor;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	foreach (int Sayi in SiraliListe.Reverse())
	{
		Console.WriteLine(Sayi);
	}

	Console.ReadLine();
}
Çıktı : 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

Clear() methodu, tüm elemanları silmeye yarıyor;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	SiraliListe.Clear();

	Console.ReadLine();
}

Min ve Max özellikleri sayesinde listedeki en küçük ve en büyük değerli elemanlara ulaşabiliriz;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	Console.WriteLine("Min : {0}, Max : {1}", SiraliListe.Min, SiraliListe.Max);

	Console.ReadLine();
}
Çıktı : Min : 1, Max : 10

For – ForEach – List.ForEach performans karşılaştırması

31 October 2010 1 yorum

Bir dizinin tüm elemanları üzerinde bir aksiyon gerçekleştirmemiz gerektiğinde, sıklıkla şu üç yoldan birini kullanırız;

  • For döngüsü
  • ForEach Döngüsü
  • List generic sınıfının ForEach extension method’u

Şimdi basit bir örnek ile bu üç yöntemi karşılaştıralım (*);

(* Not : Karşılaştırmalar; Windows7 64bit kurulu, Core2Duo 3.0 GHz ve 4 GB Ram’li bilgisayarımda yapılmıştır. Sadece fikir verme amaçlıdır, farklı durumlarda faklı sonuçlar ile karşılaşılabilir.)

Öncelikle parametre olarak Generic List (List<T>) alan üç tane method yazalım;

private static long ToplamFor(List<int> Liste)
{
	long Sonuc = 0;
	int ListeAdet = Liste.Count;

	for (int iLoop = 0; iLoop < ListeAdet; iLoop++)
		Sonuc += Liste[iLoop];

	return Sonuc;
}

private static long ToplamForEach(List<int> Liste)
{
	long Sonuc = 0;

	foreach (int Rakam in Liste)
		Sonuc += Rakam;

	return Sonuc;
}

private static long ToplamForEachExtension(List<int> Liste)
{
	long Sonuc = 0;

	Liste.ForEach(Rakam => Sonuc += Rakam);

	return Sonuc;
}

Aynı testi 10 defa gerçekleştirip, ortalamasını alacak bir test fonksiyonu yazalım. Yazacağımız fonksiyonu test listesinde olacak eleman adedini parametre olarak alacak;

private static void Testler(int ListeElemanAdet)
{
	List<int> ForSureler = new List<int>();
	List<int> ForEachSureler = new List<int>();
	List<int> ForEachExtensionSureler = new List<int>();

	List<int> TestVerisi = Enumerable.Range(0, ListeElemanAdet).ToList();

	Stopwatch sw = new Stopwatch();

	for (int iLoop = 0; iLoop < 10; iLoop++)
	{
		sw.Restart();
		ToplamFor(TestVerisi);
		sw.Stop();
		ForSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEach(TestVerisi);
		sw.Stop();
		ForEachSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEachExtension(TestVerisi);
		sw.Stop();
		ForEachExtensionSureler.Add(sw.ElapsedTicks);
	}

	Console.WriteLine("For Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForSureler.Average());

	Console.WriteLine("ForEach Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForEachSureler.Average());

	Console.WriteLine("ForEach Extension ({0} Eleman) : {1}", ListeElemanAdet, ForEachExtensionSureler.Average());
}

Artık uygulamamızın test fonksiyonunu kullanacak son kod parçasını yazabiliriz;

public static void Main(string[] args)
{
	Console.WriteLine("Test Başladı");

	Testler(1000);
	Testler(5000);
	Testler(10000);
	Testler(50000);
	Testler(100000);
	Testler(500000);
	Testler(1000000);
	Testler(5000000);
	Testler(10000000);
	Testler(50000000);

	Console.WriteLine("Test Bitti");

	Console.ReadLine();
}

Bakalım yaptığımız testler nasıl sonuç vermiş;

For - ForEach - ForEach extension Performans Karşılaştırması / Ekran Görüntüsü

Sonuçlardan aşağıdaki tabloyu çıkarttım;

Test Verisi For ForEach ForEach Extension
1.000 71,1 121,5 79,7
5.000 34,3 92,2 55,6
10.000 70,0 185,1 110,4
50.000 349,3 918,4 568,3
100.000 715,2 1.902,7 1.159,0
500.000 3.583,3 9.379,3 5.600,0
1.000.000 7.260,4 18.877,9 11.242,8
5.000.000 37.927,2 96.096,9 57.845,4
10.000.000 74.553,5 192.621,6 115.559,6
50.000.000 371.698,1 956.394,4 572.776,7

İlk olarak 50.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000 elemana kadar inceleme

Son olarak 50.000.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000.000 elemana kadar inceleme

Dizi oluşturma ve sıralama

12 March 2010 5 yorum

C# ile en basit dizi tanımlama yöntemi, değişken tipinin sonuna [] karakterlerini eklemektir.

Örnek :

int[] TekSayilar = { 3, 1, 9, 5, 7 };

string[] Ogrenciler = { "Engin", "Ahmet", "Mehmet", "Ali", "Veli" };

Dizileri sıralamak için, Array sınıfının static Sort() methodunu kullanabiliriz;

Array.Sort(TekSayilar);

Array.Sort(Ogrenciler);

Şimdi TekSayilar ve Ogrenciler dizilerindeki elemanları ekrana yazdırırsak;

foreach (int Sayi in TekSayilar)
	Console.WriteLine(Sayi);

foreach (string Ogrenci in Ogrenciler)
	Console.WriteLine(Ogrenci);

Dizilerdeki elemanların sıralanmış olduklarını görürüz.

Kelimenin son harfi ile başlayan kelime oyunu

05 January 2010 7 yorum

Eminim hepimiz, kendi aramızda, “Kelimenin Son Harfi ile Başlayan Kelime Oyunu“nu oynamışızdır.

Oyunun kuralları basittir, iki “oyuncu” karşılıklı oturur, oyunculardan biri, bir kelime söyleyerek oyunu başlatır. Sonra oyuncular sırayla, diğerinin söylediği kelimenin son harfi ile başlayan başka bir kelime söylemek zorundadır. Söyleyecek kelime bulamayan oyuncu “oyunu” kaybeder.

Gelin bu basit oyunu C# ile yazalım. Hemen ekran görüntüsü vererek başlıyorum;

Oyunu, bir Oyuncu, bir Bilgisayar Oyuncusuna karşı oynayacak. İhtiyacımız olan ilk şey, Bilgisayar Oyuncusu’nun içinden kelime seçeceği sözlük. Sözlük oluşturmak için daha önce yazdığım Web Sayfasından Sözlük Oluşturma ve Dizi Karıştırma makalelerini birleştirip kullanacağız.

btnYeniOyun butonunun Click olayında, txtAdres kontrolüne yazılmış olan web sayfasındaki kelimeler bir listeye dolduruluyor, ayıklanıyor, karıştırılıyor ve lbKullanilabilecekKelimeler ListBox kontrolünde gösteriliyor.

public static class ExtensionManager
{
	private static Random r = new Random();

	public static List<T> ListeKaristir<T>(this List<T> Liste)
	{
		List<T> tmpList = Liste.GetRange(0, Liste.Count);
		List<T> arrReturn = new List<T>();

		while (tmpList.Count > 0)
		{
			int rastgele = r.Next(0, tmpList.Count);
			arrReturn.Add(tmpList[rastgele]);
			tmpList.RemoveAt(rastgele);
		}

		return arrReturn;
	}
}
private void btnYeniOyun_Click(object sender, EventArgs e)
{
	lbKullanilabilecekKelimeler.Items.Clear();
	lbKullanilabilecekKelimeler.BeginUpdate();

	WebRequest wr = WebRequest.Create(txtAdres.Text);
	WebResponse ws = wr.GetResponse();
	StreamReader sr = new StreamReader(ws.GetResponseStream(), Encoding.UTF8);
	string response = sr.ReadToEnd();
	sr.Close();
	ws.Close();

	List<string> arrKelime = new List<string>();

	Regex r = new Regex("<(.|\n)*?>");
	foreach (string satir in r.Replace(response, "").Split(" \t\r\n({[]}),.;:*-+/?<>&%'#@=\"\\_".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
		if (satir.Trim().Length > 5 && !arrKelime.Contains(satir.Trim()))
			arrKelime.Add(satir.Trim());

	lbKullanilabilecekKelimeler.Items.AddRange(arrKelime.ListeKaristir().ToArray());

	lbKullanilabilecekKelimeler.EndUpdate();

	txtYeniKelime.Clear();
	txtOyunTarihce.Clear();
}

Oyun, birinci oyuncunun txtYeniKelime kontrolüne yazdığı kelime ile başlıyor.

string OncekiKelimeninSonHarfi = string.Empty;
private void btnYeniKelime_Click(object sender, EventArgs e)
{
	if (txtYeniKelime.Text != "" && txtYeniKelime.Text.StartsWith(OncekiKelimeninSonHarfi))
	{
		string Kelime = txtYeniKelime.Text.Trim();
		txtOyunTarihce.Text = string.Format("(O): {0}{1}{2}", Kelime, Environment.NewLine, txtOyunTarihce.Text);
		txtYeniKelime.Clear();
		KelimeSec(Kelime);
		txtYeniKelime.Focus();
	}
}

Bilgisayar Oyuncusu Sözlük’ten kelimenin son harfi ile başlayan kelimelerden bir tanesini rastgele olarak seçiyor.

Kullandığı her kelimeyi lbKullanilabilecekKelimeler ListBox kontrolünden çıkartıp, lbKullanilmisKelimeler ListBox listesine ekliyor.

private void KelimeSec(string OncekiKelime)
{
	Random r = new Random();

	var Kelimeler = (from k in lbKullanilabilecekKelimeler.Items.OfType<string>() where k.StartsWith(OncekiKelime.Substring(OncekiKelime.Length - 1, 1)) select k).ToList<string>();

	if (Kelimeler.Count == 0)
	{
		MessageBox.Show(lbKullanilmisKelimeler.Items.Count + ". Kelimede Bilgisayar Oyuncusu oynayacak Kelime bulamadı!.", "Oyun Bitti!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
		return;
	}

	int Sira = r.Next(0, Kelimeler.Count);
	string Kelime = Kelimeler[Sira];
	OncekiKelimeninSonHarfi = Kelime.Substring(Kelime.Length - 1, 1);

	lbKullanilabilecekKelimeler.Items.Remove(Kelime);
	lbKullanilmisKelimeler.Items.Add(Kelime);

	txtOyunTarihce.Text = string.Format("(B): {0}{1}{2}", Kelime, Environment.NewLine, txtOyunTarihce.Text);
}

Oyun, Bilgisayar Oyuncusu’nun kelime bulamamasına kadar devam ediyor.

Oyunun kaynak kodlarını buradan indirebilirsiniz.

C# ile Dizi Bölümleme

30 December 2009 Yorum yapılmamış

Bilgeadam’da öğrencilerimden birinin sorduğu soru üzerine, bir dizinin, belli sayıda elemanlardan oluşan alt dizilere bölünmesi ile ilgili aşağıdaki uygulamayı yazdım.

Uygulama şöyle çalışıyor; rastgele kelimelerden oluşan bir dizimiz var, bu diziyi, n elemanlı alt dizilere bölmek istiyoruz.

Hemen kolları sıvayalım ve kod yazmaya başlayalım.

Öncelikle rastgele kelime oluşturma fonksiyonunu yazalım;

const string Harfler = "abcdefghijklmnopqrstuvwxyz";
Random r = new Random();

public string RastgeleKelimeUret(int HarfAdet)
{
	char[] arrReturn = new char[HarfAdet];

	Parallel.For(0, HarfAdet, iLoop => {
		arrReturn[iLoop] = Harfler[r.Next(0, Harfler.Length - 1)];
	});

	return new string(arrReturn);
}

Bu fonksiyonu C# ile Dizi Karıştırma yazımdan hatırlayacaksınız. Şimdi bu fonksiyonu kullanarak List<string> tipinde bir diziye 25 eleman dolduran kodumuzu yazalım;

List<string> BolunecekDizi = new List<string>();
Parallel.For(5, 25, iLoop => {
	BolunecekDizi.Add(RastgeleKelimeUret(iLoop));
});

Parallel For kullanarak Multi-Core ve Multi-Thread destekli kod yazdığımıza dikkat edelim. Bölümleme fonksiyonunu ExtensionMethod olarak yazacağız.

public static class ExtensionManager
{
	public static List<T>[] Bolumle<T>(this List<T> Dizi, int ParcaAdet)
	{
		if (Dizi == null)
			throw new Exception("Dizi boş olamaz..");

		if (ParcaAdet < 1)
			throw new Exception("Parça Adet 1'den küçük olamaz..");

		int DiziBoyu = (int)Math.Floor(Dizi.Count / (double)ParcaAdet) + 1;

		List<T>[] arrReturn = new List<T>[DiziBoyu];

		int Adim = 0;
		Parallel.For(0, Dizi.Count, iLoop => {
			if (iLoop % ParcaAdet == 0 && iLoop > 0)
				Adim += 1;

			if (arrReturn[Adim] == null)
				arrReturn[Adim] = new List<T>();

			arrReturn[Adim].Add(Dizi[iLoop]);
		});

		return arrReturn;
	}
}

Artık tek yapmamız gereken List<T> generic tipinde nesnelerde Bolumle() fonksiyonunu kullanmak olacak.

List<string>[] Bolumler = BolunecekDizi.Bolumle(3);

Uygulamanın kaynak kodlarını buradan indirebilirsiniz.