<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CETURK &#187; C# ile soundex</title>
	<atom:link href="http://www.ceturk.com/etiket/c-ile-soundex/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ceturk.com</link>
	<description>Türkiye&#039;nin Bilişim Platformu</description>
	<lastBuildDate>Wed, 08 Sep 2010 08:53:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>C# ile Soundex Algoritması(Bunu mu demek istediniz?)</title>
		<link>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html</link>
		<comments>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html#comments</comments>
		<pubDate>Sun, 01 Nov 2009 13:08:59 +0000</pubDate>
		<dc:creator>Olcay KÜK</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[bunu mu demek istediniz]]></category>
		<category><![CDATA[C# ile soundex]]></category>
		<category><![CDATA[soundex]]></category>
		<category><![CDATA[soundex algoritması]]></category>
		<category><![CDATA[Yasin Sirkecili]]></category>

		<guid isPermaLink="false">http://www.ceturk.com/?p=3467</guid>
		<description><![CDATA[Herkese merhabalar bu makalemizde Fonetik algoritmalar içerisinde önemli bir yer tutan Soundex algoritmasını inceleyeceğiz. İnsanoğlunun uzun yıllar boyunca süren zeka gelişimi evrelerine baktığımızda, her yeni dönemin, dünyayı tanıma evrelerinin getirdiği yeni bilgi akışları ve bu bilgilerin kullanımlarına dair uygulanabilirlikleri tanımladığını görebiliriz. 18. Yüzyıldan bu yana insanoğlu matematik ve fizik alanlarında birçok yeni buluşlar yapmış ve [...]]]></description>
			<content:encoded><![CDATA[<p>Herkese merhabalar bu makalemizde Fonetik algoritmalar içerisinde önemli bir yer tutan Soundex algoritmasını inceleyeceğiz. İnsanoğlunun uzun yıllar boyunca süren zeka gelişimi evrelerine baktığımızda, her yeni dönemin, dünyayı tanıma evrelerinin getirdiği yeni bilgi akışları ve bu bilgilerin kullanımlarına dair uygulanabilirlikleri tanımladığını görebiliriz. 18. Yüzyıldan bu yana insanoğlu matematik ve fizik alanlarında birçok yeni buluşlar yapmış ve bu buluşların eğitim öğretim hayatına aktarılmasıyla insan zihninin hiç olmadığı kadar zorlanarak geliştirilebilmesine olanak sağlamıştır.<span id="more-3467"></span></p>
<p>Yarım asır geriye döndüğümüzde bile daha az bilgi havuzu içerisinde yaşayan toplumların hafızalarını incelediğimizde karmaşa içerisinde olmayan net ve temiz bilginin hafızaya olan etkilerinin aynı doğrultuda olduğunu görebiliriz. Ancak günümüze geldiğimizde tüm dünyanın bir metropol trafiği kadar hızlı ve karmaşık bir bilgi çöplüğü haline geldiğini söylemek sanırım çok yanlış olmaz. Karmaşık ve aşırı bilginin/verinin çoğu zaman hafızalarımızda hatırlanması zor yada kısmi hatırlama süreçlerine neden olduğunu söyleyebiliriz.</p>
<p>Veri depolama ve sorgulama tekniklerinin bilgisayar ortamında geliştirilmesinden bu yana insan hayatının derin ölçülerde kolaylaştırıldığı aşikar. Artık hep hayal gözüyle baktığımız algılama ve öğrenme yeteneğine sahip yapay zeka uygulamalarından söz edebiliyoruz.</p>
<p>Örneğin text türünde verileri ararken aradığımız kelimenin bir kısmını girerek sonuca ulaşmamız yada doğru hatırlayamadığımız bir kelimenin bir kısmını girerek benzer sonuçları bulabilmemiz oldukça kolay. İşte Soundex algoritmasının uygulamalarımıza sağladığı faydalardan biride tam olarak bu noktada karşımıza çıkıyor.Bir makale için bu kadar uzun bir giriş yaparak buraya kadar okumanıza sebep olmam hoşunuza gitmemiş olabilir. Ancak fonetik algoritmaların değerinin sadece yanlış girilen veya benzer veriler ile karşılaştırma yapmaktan öte hafızamızda tam olarak kalmayan verileri bulmamızı sağladığı gerçeğini de göstermek istedim.</p>
<p>Şimdi nedir Soundex algoritması nasıl çalışır ona bakalım;</p>
<p>Soundex algoritması gelişmiş birçok veritabanın içeriğinde hazır bir fonksiyon olarak gelen telaffuz aşamasında birbirine ses benzerliği olan kelimeleri bulmamızı sağlayan basit bir algoritmadır. Robert Russell ve Margaret Odell tarafından geliştirilmiştir. Çalışma mantığı tek bir kelime için 5 temel aşamadan oluşur. Bu aşamaları şöyle sıralayabiliriz;</p>
<p>1-) Kelimenin ilk harfi olduğu gibi kalır.<br />
2-) İlk harf haricindeki harfler arasından A, E , H , I, O , U, W, Y harfleri çıkartılır.<br />
3-) Yine ilk harf haricindeki harfler arasından aşağıdaki listeye uygun olarak harfler numaralara çevrilir.</p>
<p><img class="alignnone size-full wp-image-3475" title="Adsız" src="http://www.ceturk.com/images/Adsız.jpg" alt="Adsız" width="302" height="122" /></p>
<p>4-) Yan yana olan aynı harf yada aynı numara kümesine dahil olabilecek harfler tekile indirilir.<br />
5-) Bu şekilde oluşturulan metin 4 haneli olana kadar eksik karakterler 0 ile tamamlanır.</p>
<p>Soundex algoritması MSSQL , Oracle, MySQL gibi birçok veritabanında hazır olarak gelse de Veritabanı kullanmadığımız yada verilerimizin disconnected layer olarak bulunduğu durumlarda veya veritabanı olarak kullanılan dosyanın (Örn; Excel) soundex algoritmasını içermediği durumlarda mevcut veriler üzerinde bu algoritmayı nasıl kullanabileceğimizi inceleyelim,</p>
<p>İlk olarak Soundex adında bir fonksiyonu Extension Method olarak kullanabilmek adına static bir class yaratıyoruz ve içerisinde Soundex adında string tipindeki fonksiyonumuzu yazıyoruz.</p>
<p><img class="alignnone size-full wp-image-3468" title="soundex1" src="http://www.ceturk.com/images/soundex1.jpg" alt="soundex1" width="323" height="209" /></p>
<p>İlk olarak Soundex adında bir fonksiyonu Extension Method olarak kullanabilmek adına static bir class yaratıyoruz ve içerisinde Soundex adında string tipindeki fonksiyonumuzu yazıyoruz.</p>
<p>Kodlarımıza bakacak olursak;</p>
<div>
<pre class="brush:csharp">static class ExtensionMethods
{
public static string Soundex(this string exp)
{
string deger = String.Empty;
if (exp.Length &gt; 1)
{
deger = exp.Substring(0, 1);
exp = exp.Substring(1, exp.Length - 1);

exp = exp.Replace("Ğ", "G");
exp = exp.Replace("Ü", "U");
exp = exp.Replace("Ş", "S");
exp = exp.Replace("Ö", "O");
exp = exp.Replace("İ", "I");
exp = exp.Replace("Ç", "C");

exp = exp.Replace("A", "");
exp = exp.Replace("E", "");
exp = exp.Replace("H", "");
exp = exp.Replace("I", "");
exp = exp.Replace("O", "");
exp = exp.Replace("U", "");
exp = exp.Replace("W", "");
exp = exp.Replace("Y", "");

string karakter = "";
string o_karakter = "";

for (int i = 0; i &lt; exp.Length; i++)
{
int code = new int();

karakter = exp[i].ToString();
if ("BFVP".Contains(karakter))
{
code = 1;
}
else if ("CGJKQSXZ".Contains(karakter))
{
code = 2;
}
else if ("DT".Contains(karakter))
{
code = 3;
}
else if ("L".Contains(karakter))
{
code = 4;
}
else if ("MN".Contains(karakter))
{
code = 5;
}
else if ("R".Contains(karakter))
{
code = 6;
}
if (karakter != o_karakter)
{
if (deger.Substring((deger.Length - 1), 1) != code.ToString())
{
deger += code.ToString();
}
}
if (deger.Length == 4)
{
break;
}
if (karakter != "")
{
o_karakter = karakter;
}
}
int uzunluk = deger.Length;
for (int j = 0; j &lt; (4 - uzunluk); j++)
{
deger += "0";
}
}
return deger;
}
}</pre>
</div>
<p>İlk olarak “deger” adında yeni bir string değişken yaratıyoruz bu değişkene bizim fonksiyondan geriye değer döndereceğimiz değişken diyebiliriz.</p>
<p>Fonksiyona ait string tipindeki parametremiz olan exp değişkenin karakter uzunluğu eğer 1 karakterden fazla ise işlem görmesini sağlıyoruz.</p>
<div>
<pre class="brush:csharp">deger = exp.Substring(0, 1);
exp = exp.Substring(1, exp.Length - 1);</pre>
</div>
<p>Yeni oluşacak katarımızda 1. Madde de olduğu üzere metnin ilk karakterini deger stringine aktarıyoruz ve exp stringi içerisinden bu karakteri çıkartıyoruz.</p>
<div>
<pre class="brush:csharp">exp = exp.Replace("Ğ", "G");
exp = exp.Replace("Ü", "U");
exp = exp.Replace("Ş", "S");
exp = exp.Replace("Ö", "O");
exp = exp.Replace("İ", "I");
exp = exp.Replace("Ç", "C");</pre>
</div>
<p>Soundex algoritmasına ait bu makalede anlattığımız dizilim İngilizce için geçerli olduğunu belirtmek isterim. Ancak biz bu makalemizde Türkçe harfleri İngilizce alfabesinde varolan şekilsel benzerlikleri ile değiştiriyoruz. Aslında bu anlamda daha ciddi bir çalışma yapılarak telaffuz hususundaki harf benzerliklerini daha net belirlemek için ilgili kurumların bilimsel çalışmalarından yararlanılabilir.</p>
<p>Algoritmamızın devam eden kısmında 2. Madde de olduğu üzere;</p>
<div>
<pre class="brush:csharp">exp = exp.Replace("A", "");
exp = exp.Replace("E", "");
exp = exp.Replace("H", "");
exp = exp.Replace("I", "");
exp = exp.Replace("O", "");
exp = exp.Replace("U", "");
exp = exp.Replace("W", "");
exp = exp.Replace("Y", "");</pre>
</div>
<p>A,E,H,I,O,U,W,Y harflerini exp stringimizden çıkartıyoruz.<br />
3. maddemizde belirtilen harf kümelerine göre sayısal değerler vermek amacıyla for döngüsüne başlamadan önce</p>
<div>
<pre class="brush:csharp">string karakter = "";
string o_karakter = "";</pre>
</div>
<p>şeklinde 2 string tipli değişken yaratıyoruz bu değişkenlerden “karakter” o an işlem yaptığımız karakter değerini alırken “o_karakter”(önceki karakter) döngü sonunda son aktarılan karakteri bir sonraki değer artışında saklamak için tutacak.</p>
<div>
<pre class="brush:csharp">for (int i = 0; i &lt; exp.Length; i++)
{
int code = new int();

karakter = exp[i].ToString();</pre>
</div>
<p>exp değişkeni içerisindeki 1. Karakteri deger stringe aktardığımız için kalan karakterler arasında 0. Karakterden başlayarak her karakterin “karakter” stringine aktarılmasını sağlıyor ve aşağıdaki if bloguyla devam ederek ilgili karaktere karşılık gelen sayısal değeri buluyoruz.</p>
<div>
<pre class="brush:csharp">if ("BFVP".Contains(karakter))
{
code = 1;
}
else if ("CGJKQSXZ".Contains(karakter))
{
code = 2;
}
else if ("DT".Contains(karakter))
{
code = 3;
}
else if ("L".Contains(karakter))
{
code = 4;
}
else if ("MN".Contains(karakter))
{
code = 5;
}
else if ("R".Contains(karakter))
{
code = 6;
}</pre>
</div>
<p>For döngümüz içerisinde son olarak 4. Maddede belirttiğim üzere yan yana aynı harf yada aynı sayısal değere sahip olabilecek harfleri tekil hale indirgeyeceğiz.</p>
<div>
<pre class="brush:csharp">if (karakter != o_karakter)
{
if (deger.Substring((deger.Length - 1), 1) != code.ToString())
{
deger += code.ToString();
}
}
if (deger.Length == 4)
{
break;
}
if (karakter != "")
{
o_karakter = karakter;
}
}</pre>
</div>
<p>Şimdi buraya kadar yaptıklarımızı kısaca test etmek için sayfaya bir adet textbox,label ve buton ekliyorum. Butona tıklandığında textbox içerisindeki ifadenin soundex methodunu kullanarak yeni oluşturduğu stringi labelin text propertysine aktaracağız.</p>
<div>
<pre class="brush:csharp">protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = TextBox1.Text.Trim().ToUpper().Soundex();
}</pre>
</div>
<p><img class="alignnone size-full wp-image-3469" title="soundex2" src="http://www.ceturk.com/images/soundex2.jpg" alt="soundex2" width="232" height="67" /></p>
<p>Resimde de gördüğünüz üzere soundex fonksiyonundan geriye dönen değer Y250 olarak Label nesnesine aktarıldı.<br />
Textbox içerisinde yazdığımız ifadeye göre algoritmayı karşılaştıracak olursak fonksiyonumuzun çalışmasını şöyle izah edebiliriz.</p>
<p>1-) &#8220;Y&#8221; karakterini alır ve ifadeden çıkartır.<br />
2-) ”İ” karakterini “I” ya çeviriyor sonra &#8220;A&#8221; ve &#8220;I&#8221; karakterlerini ifade içerisinden çıkartıyor.(Buraya kadar yaptığımız işlemlerle ifademizde artık SN karakterleri kalır)<br />
3-) &#8220;S&#8221; karakterine karşılık gelen “2” ile &#8220;N&#8221; karakterine karşılık gelen “5” değerlerini yeni stringimize aktarır.<br />
4-) Yeni oluşan string değerimiz for döngüsü sonunda Y25 halinde bulunduğundan ve ifade içerisinde başka karakter olmamasından ötürü yeni stringimizi 4 karakterli yapabilmek amacıyla sonunda bir tane “0” ekliyor.</p>
<p>Böylelikle algoritmamızın soundex algoritmasının açıklamasında belirttiğimiz maddelere göre doğru çalıştığını söyleyebiliriz.<br />
Şimdi mevcut fonksiyonumuzu kullanmak amacıyla Access veritabanında varolan değerler içerisinde yanlış yazdığımız bir karakteri bulmamızı sağlayacak küçük bir aplikasyon hazırlayabiliriz.</p>
<div>
<pre class="brush:csharp">protected void Button1_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OleDb.12.0;Data Source=D:\postakodlari.mdb");
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select TOP 1 ILADI from pkod where ILADI=@ILADI";
cmd.Parameters.Add(new OleDbParameter("@ILADI",TextBox1.Text.Trim()));
conn.Open();
if (cmd.ExecuteScalar() == null)
{
OleDbDataAdapter adapter = new OleDbDataAdapter("select distinct ILADI from pkod order by ILADI", conn);

DataTable dtable = new DataTable();
adapter.Fill(dtable);
conn.Close();
string metin = TextBox1.Text.Trim().ToUpper().Soundex();
System.Collections.ArrayList alist = new ArrayList();
for (int i = 0; i &lt; dtable.Rows.Count; i++)
{
if (dtable.Rows[i]["ILADI"].ToString().Soundex() == metin)
{
alist.Add(dtable.Rows[i]["ILADI"].ToString());
}
}
if (alist.Count != 0)
{
Label1.Text = "Bunumu demek istediniz?: ";
for (int i = 0; i &lt; alist.Count; i++)
{

Label1.Text += alist[i].ToString();
if (i != (alist.Count - 1))
{
Label1.Text += ",";
}
}
}
else
{
Label1.Text = "aradığınız kritere uygun bir sonuç bulunamadı";
}
conn.Close();
}
else
{

Label1.Text = "sorgulanan veri mevcuttur: " + cmd.ExecuteScalar().ToString();
conn.Close();
}
}</pre>
</div>
<p>Aplikasyonumuzu kısaca şöyle açıklayabiliriz;</p>
<p>Postakodlari.mdb veritabanı içerisinde bulunan pkod tablosundaki ILADI kolonu içerisinde arama yapacağız eğer textbox içerisine girilen veri mevcutsa label’ın text propertysine sonucun varolduğuna dair</p>
<p><img class="alignnone size-full wp-image-3470" title="soundex3" src="http://www.ceturk.com/images/soundex3.jpg" alt="soundex3" width="252" height="61" /></p>
<p>“Sorgulanan veri mevcuttur: “</p>
<p>şeklinde bir metin aktarıyoruz.<br />
Eğer aranılan veri yoksa ve kolondaki değerlerin soundex fonksiyonu sonucunda aranılan veriye benzer veriler ile karşılaşıyorsak bu verilerin alist adındaki ArrayList’imize aktarılmasını sağlıyoruz.</p>
<p>İşlem sonucunda alist adındaki ArrayList’imizin Count değeri sıfırdan farklı ise label’ın text property’sine bu değerleri aralarına virgül koyarak yazdırıyoruz.</p>
<div>
<pre class="brush:csharp">if (alist.Count != 0)
{
Label1.Text = "Bunu mu demek istediniz?: ";
for (int i = 0; i &lt; alist.Count; i++)
{

Label1.Text += alist[i].ToString();
if (i != (alist.Count - 1))
{
Label1.Text += ",";
}
}
}</pre>
</div>
<p><img class="alignnone size-full wp-image-3471" title="soundex4" src="http://www.ceturk.com/images/soundex4.jpg" alt="soundex4" width="252" height="61" /><img class="alignnone size-full wp-image-3472" title="soundex5" src="http://www.ceturk.com/images/soundex5.jpg" alt="soundex5" width="252" height="61" /></p>
<p>Eğer alist in count değeri sıfır ise;</p>
<div>
<pre class="brush:csharp">else
{
Label1.Text = "aradığınız kritere uygun bir sonuç bulunamadı";
}</pre>
</div>
<p>Şeklindeki değerimizi aktarıyoruz.</p>
<p><img class="alignnone size-full wp-image-3473" title="soundex6" src="http://www.ceturk.com/images/soundex6.jpg" alt="soundex6" width="282" height="55" /></p>
<p>Hepsi bu kadar…</p>
<p>Şunu hatırlatmak isterim. Google’ın “Bunu mu demek istediniz?” şeklinde kullanıcılara gösterdiği sonuçlar Ori Allon tarafından geliştirilen Orion algoritması çerçevesinde ki veriler ile karşılaştırılmaktadır. Bu sebeple ürettiğiniz sonuçlarda google ile birebir aynı neticelere erişemeyebilirsiniz. Ancak bu algoritmayı kendi projelerinizde kullanabilirsiniz.</p>
<p>Tüm yazılımcı arkadaşlara mutlu günler dilerim…</p>
<p>İyi çalışmalar,<br />
<strong>Yasin SİRKECİLİ</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
