inicio mail me! sindicaci;ón

Code Jam – Problem B. Reverse Words

Yaklaşık 5 gün sonra Round 1A 2012 Google Code Jam yarışması başlıyor. Bu kez vakit bulabilirsem katılmayı düşünüyorum. Daha önceki yarışmalarda sorulmuş soruları inceleyerek en azından pratik yapmak istedim. Geçen yıl Google Code Jam Africa’da sorulmuş olan sorulardan birini C#’da çözerek işe başladım.

Verilen Örnek

Yukarıdaki input bize bir dosyada veriliyor ve sağdaki output isteniyor. Basit bir reverse işlemi ama bu yarışma da çözüm kadar performasında önemli olduğunu gözardı etmemek lazım. Örneğin, geniş set bir input için 4 dakikayı aşan çözümler sonuç olarak doğru output’u versede, doğru kabul edilmiyor. Benim c# çözümüm aşağıdaki gibi oldu. 100 satırlık bir input için yaklaşık 4 milisaniye sürüyor.

Muhtemelen makine diline daha yakın diller performans açısından daha olumlu sonuç verecektir. Denemedim ama vakit bulursam en azından c’de deneyeceğim. Varsa siz de çözümlerinizi paylaşabilirsiniz.


            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();

            using (StreamReader sr = new StreamReader(@"c:\B-large-practice.in.txt"))
            {
                using (StreamWriter sw = new StreamWriter(@"c:\B-large-practice.out.txt"))
                {
                    int n = int.Parse(sr.ReadLine());

                    for (int i = 1; i < n; i++)
                    {
                        string[] str = sr.ReadLine().Split(' ');

                        StringBuilder sb = new StringBuilder();

                        for (int j = str.Length - 1; j >= 0; j--)
                        {
                            sb.Append(str[j] + " ");
                        }

                        sw.WriteLine("Case #{0}: {1}", i, sb.ToString());
                    }
                }
            }

            stopWatch.Stop();
            Console.WriteLine(stopWatch.ElapsedMilliseconds);

INPUT ve OUTPUT dosyalarını buradan indirebilirsiniz.

Eşit Eşit Eşit de Neyin Nesi ?

Javascript’de === , !== operatörleri katı karşılaştırma operatörleri ( strict comparison operators ) olarak bilinirler.  == ve != ile tip bağımsız karşılaştırmalar yapabilirken, bu operatörler karşılaştırma yaparken tipleri gözardı etmez.

Aşağıdaki örnek üzerinden bunlar arasındaki farkı daha iyi anlayabileceksiniz.


C#’da ya da JAVA’da bu tip operatörler bulunmamakla birlikte, eğer olsaydı herhalde şunun gibi birşey olurdu.

bool TripleEqual(object obj1, object obj2)
{
        return obj1.GetType() == obj2.GetType() && obj1.Equals(obj2);
}

Belirlediğiniz Kolonlara Göre Tekrarlayan Satırları İlgili Tablodan Silmek (Delete Duplicate Rows in a Table)

Zaman zaman veritabanına script geçerken use BuVeritabanı yerine use ŞuVeritabanı diyerek, tablolarda birden fazla tekrarlayan alana sebebiyet vermem nedeniyle bu tekrarlayan alanları silecek bir SP (Store procedure) yazmaya karar verdim. Önceden basit bir sql sorgusu ile bunu hallederken, daha dinamik birşeyler oluşturmak istedim ve herşey bununla başladı. Bir yandan yeni birşeyler öğrenirken, diğer yandan bildiklerimi pekiştirme fırsatı buldum.

1- Sql cümlelerinde from’dan sonra @Degisken kullanamıyoruz. Örn: (Select * from @TableName — HATALI)
2- Temp tablolar mevcut tablonun kopyasını oluşturur, onları işaret etmezler. Bu da temp tablolar üzerinde yapılacak delete, update, insert gibi işlemlerin yalnızca temp tabloya etki edeceğiniz.
3- View ise ilgili tablodaki alanlara işaret eder. Tablo güncellendiği an view güncellenir ; view’de bir işlem yapılırsa asıl tablo güncellenir.

Aşağıdaki store procedure ilk parametre olarak tablo adı, ikinci parametre olarak bir ya da birden fazla kolon adı, üçüncü parameter olarak hangi kolona göre sıralama yapacağı, son olarak da bu sıralamanın artan mı(ASC) azalan mı(DESC) olacağını belirtiyor. 3. ve 4. parametre opsiyonel olmakla birlikte, girilmedikleri takdirde mevcut sıra korunarak işlem yapılıyor.

Sonuç olarak ilgili tablo için kolon adlarına göre gruplandırma yaparak, tekrarlayan alanları buluyor ve siliyoruz.


	create proc DeleteDuplicateRows
	(
		@TableName varchar(100),
		@Columns varchar(100),
		@OrderBy varchar(100) = '(select 0)',
		@Sort varchar(10) = ''
	)
	as
		declare @Sql varchar(max)
		set @Sql = 'create view DuplicatedValueView select ROW_NUMBER() over (partition by ' + @Columns + ' order by ' + @OrderBy + ' ' + @Sort + ') as RowNumber from ' + @TableName
		exec(@sql)
		set @Sql = 'delete from DuplicatedValueView where RowNumber > 1'
		exec(@Sql)
		set @Sql = 'drop view DuplicatedValueView'
		exec(@Sql)

Aşağıdaki sorgu ile ilk adı, soyadı ve doğum tarihi alanlarına göre partition by özelliğini kullanarak gruplandırma yapıyoruz. Bu gruplandırmayı da eklenme tarihine göre artan sırayla sıralıyoruz. İlk ad, soyad ve doğum tarihi aynı olan satırlardan sonradan eklenmiş olan satırların tümünü siliyoruz.

exec DeleteDublicateRows 'Member','FirstName, LastName, Birthdate', 'InsertTime', 'ASC'

İyi çalışmalar,

Bir Veritabanındaki Tabloyu Sql İfadesi ile Farklı Bir Veritabanına Kopyalama

Sql Server’da herhangi bir veritabanındaki bir tabloyu verileriyle ya da verileri olmadan başka bir veritabanında da oluşturmak istediğimde genellikle Sql Server’ın Generate Scripts özelliğinden yararlanıyordum. Ancak bu işlemi direkt olarak bir sql ifadesi yazarak yapmak da mümkün.

Select * Into YeniTestDB.dbo.YeniFilmler
         From Filmler
         Where 1 = 2

Bu ifade ile Filmler isimli tablo YeniTestDB isimli veritabanında da oluşturulmuş oldu. Ancak yazmış olduğunuz where ifadesi sayesinde mevcut tablodaki verilerin aktarılmasını engellendi.

Eğer buradaki where ifadesi kaldırılırsa bu kez verileriyle birlikte Filmler isimli tablo, YeniTestDB isimli veritabanında oluşturulmuş olacaktı.

ConnectionString’i UI Yardımıyla Yazmak

Çok sık kopyalanıp yapıştırılan birşey olduğu için mi, her projede genelde bir sefer yazıldığı için mi, yoksa farklı bir özel nedeni var mı bilemiyorum ancak ConnectionString’in yazılışını genelde sıkça unutuyorum. Bu sebeple şimdiye kadar ConnectionStrings.com isimli siteden sıkça yararlanıyordum. Ancak geçenlerde bana daha basit gelen bir yöntem öğrendim.

Windows kullanıyorsanız eğer, adı önemli olmamakla birlikte uzantısı udl (universal data link) olan bir dosya oluşturun ve oluşturulan dosyayı çift tıkla açın.

Karşınıza aşağıdaki gibi, veritabanı ayarlarını yapabileceğiniz bir panel açılacak.

Buradan veritabanı bağlantınız için gerekli tüm ayarları yaptıktan sonra dosyayı bir notepad aracılığıyla açın. ConnectionString karşınızda.

[oledb]
; Everything after this line is an OLE DB initstring
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=TestDB;Data Source=TRABZON

« Previous entries · Önceki Yazılarım