Thread overview
Dilim Üzerinden Dizi Elemanlarını Bul&Değiştir
Aug 18, 2012
Salih Dinçer
Aug 18, 2012
Salih Dinçer
August 18, 2012

Merhaba,

Şurada (http://ddili.org/forum/thread/931) başlayan bir tartışma, beni bir bug macerası (http://ddili.org/forum/thread/932)nın öğrettiği bilgiler ile tanıştırdı. Belki std.array içinde benzer algoritmalar vardır. Ancak bir şeyi kendin yapma, keşfetme ve öğrenme gibisi yok. İşte başlığın konusu olan kod:

import std.stdio;

auto araBul(char[] kaynak, string aranan) {
   size_t dizin;
   char[] dilim;

   while(dizin < kaynak.length-aranan.length) {    // kaynak'ın sonuna kadar aranan'ı bul
       dilim = kaynak[dizin..dizin+aranan.length];
       if(dilim == aranan) return dilim;    // bulduysa bu dilim'i aktarır,
       ++dizin;
   }
   return null;    // bulamadıysa boş döndür...
}

void birebirAktar(T)(T[] hedef, T[] aktar) {
   size_t SINIR = hedef.length <= aktar.length ?
                  hedef.length-1 : // hedef büyükse =>
                  aktar.length-1;
   while(SINIR+1) {
       hedef[SINIR] = aktar[SINIR];
       SINIR--;
   }
}

int main() {
 char[] deneme = "C Dili".dup;
 deneme.writeln; // C Dili

 //araBul(deneme, "Dil") = "Pir".dup;/* TOGGLE CODE
 birebirAktar!char(araBul(deneme, "Dil"), "Pir".dup);//*/
 deneme.writeln; // C Piri

 birebirAktar!char(araBul(deneme, "C"), "D".dup);
 deneme.writeln; // D Piri

 return 0;
}

Çıktısı:
'C Dili
C Piri
D Piri
'
Ancak bir sorun daha var! O da 'birebirAktar()' isminde bir işleve ihtiyaç duymam. Çünkü doğrudan eşitleyince gizlediğim satırın "'...is not an lvalue'" hatasını veriyor. Aşağıdak şekilde de denediğimizde, aslında dilim başka bir bellek bölgesini (.dup olan yeri) gösterdiği için bir işe yaramıyor. Başka çözüm bilen var mı?

auto dilim = araBul(deneme, "Dil");
      dilim = "Pir".dup;

Teşekkürler...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 18, 2012

Çok çok teşekkürler, işte şimdi lezzetli bir hal aldı. Aslında .dup olmadan cast()'ler ile çok daha iğrenç gözüküyordu ama şimdi D'de de çalışabilmesi iyi. Bir de C varyasyonundaki boş olup olmadığı özelliğini ekledim mi başka ne eklenebilir ki...

 char[] deneme = "C Dili".dup;
 deneme.writeln; // C Dili

 araBul(deneme, "Dil")[] = "Pir".dup;
 deneme.writeln; // C Piri

 araBul(deneme, "C")[] = "D".dup;
 deneme.writeln; // D Piri

Tek kelimeyle süper...

Önce .ptr'nin sadakati, sonra .dup'un huzur dolu görüntüsü ve şimdi köşeli parantezler ile dört köşe oldu...:)

Son olarak Ali hocamın, CevizNet'deki çözümünü de eklersek bulamadığı değişkenler için korumaya almış olacağız:
http://forum.ceviz.net/c-c/120082-c-uzerine-cok-temel-sorular-4.html#post706655

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 18, 2012

araBul'un bulduğu yerdeki karakterleri değiştirmek istiyoruz, değil mi? Bulduğundan emin olmak için önce dönüş değerinin null olmadığına bakmak gerek.

lvalue ile ilgili olan sorunun yanıtı şu: araBul() bir dilim döndürüyor. O dilim, kendisi bir değişkendir. Ancak, bir işlevin isimsiz dönüş değeri olduğu için bir rvalue'dur. (Kabaca, adresi alınan bir değişken değildir.)

Öyle bir değişkeni bir atama işlecinde şöyle kullanıyoruz:

   bir_rvalue = "Pir".dup;

Yani o değişkenin değerini değiştirerek onun artık "Pir"in bir kopyasına erişim sağlamasını istiyoruz.

Bence sen burada "o değişkenin eriştirdiği karakterleri Pir yap" demek istiyorsun. O zaman dilimin bütün elemanları üzerinde işlem yapan [ ve ] karakterlerini kullanmamız gerekir:

   araBul(deneme, "Dil")[] = "Pir".dup;

Dikkat edersen, o rvalue ile ilgileneceğimize onu yerel bir değişkene de atayabilir ve onu da kullanabilirdik. Ancak, [ ve ] karakterleri yine de gerekir:

   auto sonuç = araBul(deneme, "Dil");
   sonuç = "Pir".dup;   // YANLIŞ (yeni karakterlere erişim sağlamaya başlar)

"Eriştirdiği karakterleri değiştir" anlamında:

   auto sonuç = araBul(deneme, "Dil");
   sonuç[] = "Pir".dup; // DOĞRU (eriştirmekte olduğu karakterleri değiştirir)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]