Forum: Ders Arası RSS
Dilim Üzerinden Dizi Elemanlarını Bul&Değiştir
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Dilim Üzerinden Dizi Elemanlarını Bul&Değiştir
Merhaba,

Şurada başlayan bir tartışma, beni bir bug macerası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...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
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
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ç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-soru…
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2012-08-18, 15:44.
Değişiklik nedeni: CevizNet'e bağlantı ekledim...
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-23, 23:31:42 (UTC -08:00)