Forum: D Programlama Dili RSS
Aralıkların çalışma zamanı
kerdemdemir #1
Üye Eyl 2013 tarihinden beri · 123 mesaj · Konum: Danimarka
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Aralıkların çalışma zamanı
Merhaba,

Yeni işim dolayısıyla Ubuntu kurdum ve DMD yükledim.

Aşağıdaki gibi basit bir kodda bir sorunla karşılaştım.

Şu aralık :

    auto busRows =             stdin
                            .byLine()
                            .take(busRowCount)
                            .map!(line => line
                                  .splitter("|")
                                  .map!( a => busRowOperation(a) )
                                  .array());

writeln(busRows); satırında çalışmaya başlıyor. Fakat aralık çalışırken güncellediğim "isHasSeat" boolean'ı ne yazıkki güncellenmemiş ve yanlış yazılmış oluyor. Bu durumun önüne nasıl geçebilirim sizce ?

Bir sorumda bütün aralığı dolaşan map fonksiyonu yerine duruma bağlı olarak sadece bir kere çalışacak bir iterasyon method'u varmıdır? Aslında aşağıda görüleceği gibi isHasSeat değişkeni bir kere true 'ya çekildikten sonra hep return yapıyorum. Sizce bunun önüne geçebilirmiyim?

 
import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.range;
import std.bitmanip;
 
bool isHasSeat = false;
 
char[] busRowOperation( char[] singleRow )
{
    if ( isHasSeat )
        return singleRow; 
        
    if ( singleRow.equal( "OO" ) )
    {
        isHasSeat = true;
        return "++".dup;
    }    
    
    return singleRow; 
}
 
 
void main() {
    
    const int busRowCount = stdin.readln.strip.to!int;
 
 
    auto busRows =             stdin
                            .byLine()
                            .take(busRowCount)
                            .map!(line => line
                                  .splitter("|")
                                  .map!( a => busRowOperation(a) )
                                  .array());                   
    if ( isHasSeat )
        writeln("YES");
    else
        writeln("NO");  
              
    writeln(busRows);                        
                            
}
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ı
.array her eleman için çağrılıyor ama bütün aralık için çağrılmıyor. Dolayısıyla, busRows hevesli değil. Onun sonuna da .array eklersen YES'i baştan göreceksin.

Ama tabii, "OO"yu görene kadar çok sayıda veri varsa ve amacımız yalnızca çıktıya bir şeyler yazmaksa o kadar kopya üzücü. :) Yapacak başka bir şey de yok: veri stdin gibi çektikçe kaybolan bir kaynaktan geliyorsa işleyip bir kenara kopyalamaktan başka çare yok.

Durum bu kadar karmaşık olunca zorla aralık kullanmak yerine foreach filan daha mantıklı olabilir. :) Ama sanırım aşağıdaki doğru:
import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.range;
 
enum pattern = "OO";
 
bool rowHasSeat(const(char)[] row) {
    return row.canFind(pattern);
}
 
void main() {
    const int busRowCount = stdin.readln.strip.to!int;
 
    // Bütün giriş bu
    auto r = stdin.byLine;
 
    // Ya busRowCount adet kopyalayacağız ya da koşul sağlanana kadar.
    auto firstPart = r
                     .take(busRowCount)
                     .until!rowHasSeat(OpenRight.no)
                     // Girişin geri kalanında bu kopyaya gerek olmayacak:
                     .map!(row => row.dup)
                     .array;
 
    bool hasSeat() {
        // Hiç satır yok muydu? (Bunu daha önce de denetleyebilirdik)
        if (busRowCount == 0) return false;
 
        // Erken durduysak bulmuşuz demektir
        if (firstPart.length < busRowCount) return true;
 
        // Sonuncu eleman tuttu mu?
        if (rowHasSeat(firstPart.back)) return true;
 
        // Diğer durumda bulamamışız demektir
        return false;
    }
 
    if ( hasSeat )
        writeln("YES");
    else
        writeln("NO");
 
    // Baş tarafıyla geri kalanını birleştirip uygun işlemleri uyguluyoruz
    writeln(chain(firstPart,
                  r.take(busRowCount - firstPart.length))
            .map!(line => line
                  .splitter("|")
                  .map!( a => (a == pattern) ? "++" : a) ));
}
Ali
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:
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-22, 12:23:19 (UTC -08:00)