Forum: D Programlama Dili RSS
Haftanın Sorusu 2
Avatar
esatarslan52 (Moderatör) #1
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Uygulayarak öğrenmeyi tercih ede birisi olduğumdan C++ sınav sorularımı D ile yapıyorum. Gerçekten çok faydalı oluyor.D öğrenmeye çalışıpta çözecek soru bulamayanlar için sınav sorusunu biraz modifiye edip burayada yazıyorum.

1-Matris adından bir sınıf yazın. Matristen bir nesne oluşturulurken 3x3 float sayılar tutabilen dizi için hafızadan gerekli yeri ayıracak, nesne yok olurken de ayırdığı yeri geri verecektir(yeri geri verme işi D için bu şart değil tabiki).
2-yaz() fonksiyonu matrisi aşağıdaki şekilde ekrana yazdırın (┐=191,└=192,│=179,┘=217,┌=218).
Windows için                         Linux için
┌ 1.00 2.00 3.00 ┐             1.00 2.00 3.00
│ 4.00 5.00 6.00 │             4.00 5.00 6.00
└ 7.00 8.00 9.00 ┘             7.00 8.00 9.00
3-kalavyedenAl() fonksiyonu ile sınıfın dizi elamanına veri girşini sağlayın.
4-dizidenAl() fonksiyonu ile parametre olarak verilen 3x3 diznin elamanlarını, sınıfın dizi değişkenine aktarın.
5-diziyeDondur() fonksiyonu ile parametre olarak verile diziye, sınıfın dizi değişkenindeki elemanları aktarın.
6- "+" operatörünü iki matris sınıfını toplayacak şekilde aşırı yükleyin (m3 = m1 + m2)
7-main içinde Matris sınıfı değişkenlerini tutabilen dizi tanımlayınız.
8-Matris sınıfından değişkene kullanıcının değer girmesini sağlayınız. Bu değişkeni diziye aktarınız. Her matris değişkenin veri girişi tamamlandığında devam edip etmek istemediğini sordurunuz.
9-Veri girişi işleminden sonra dizinin tüm elemanlarının toplamını gösteren toplam matrisini ekrana yazdırınız.

Açıklamalar
    • 6.Soru sınıfların dizi değişkenlerindeki elemanlarının karşılıklı toplanması şeklinde olacak.Örneğin:
m3.mDizi[0][0] = m1.mDizi[0][0] + m2.mDizi[0][0]
m3.mDizi[0][1] = m1.mDizi[0][1] + m2.mDizi[0][1]
    • 7.Soruda bahsedilen dizi aslında bir vektör. Henüz ben dtl yi kurmayı başaramadım.Onun yerine D nin appender özelliğini kullandım.
Bu mesaj esatarslan52 tarafından değiştirildi; zaman: 2009-08-11, 05:00.
li-han #2
Üye Ağu 2009 tarihinden beri · 8 mesaj · Konum: Denizli
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
güzel soru olmuş. gelen cevaplardan çok şey öğreneceğim kesin. ben ilk iki soruyu çözmeye çalıştım. onlarıda tam çözemedim. örneğin float tipini 2 duyarlıklı gösteremedim. ayrıca (┐=191,└=192,│=179,┘=217,┌=218) karakterlerini ekrana basamadım.
şöylede bi kod yazdım beginner modda  :-)
import std.stdio;
import std.c.stdlib;
 
void main()
{
    Matris matrisim = new Matris(3,3);
    matrisim.MatrisiGöster();
    delete matrisim;
}
 
class Matris
{
    ubyte satır;
    ubyte sütun;
    
    float*[] matris;
    
    this(ubyte _satır, ubyte _sütun)
    {
        satır = _satır;
        sütun = _sütun;
        
        MatrisiOluştur();
        MatrisiDoldur();
    }
    
    void MatrisiOluştur()
    {
        matris = new float*[satır];
        
        for (int i = 0; i < sütun; ++i)
        {
            matris[i] = cast(float*)malloc(sütun);
        }
    }
    
    void MatrisiDoldur()
    {
        float değer = 1.0;
        for (int i = 0; i < satır; ++i)
        {
            for (int j = 0; j < sütun; ++j)
            {
                matris[i][j] = değer;
                değer++;
            }   
        } 
    }
    
    void MatrisiGöster()
    {
        for (int i = 0; i < satır; ++i)
        {
            for (int j = 0; j < sütun; ++j)
            {        
                write(matris[i][j], " ");
            }
            writeln();
        }
    }
    
    ~this()
    {
        delete matris;
    }
}

çıkıtı:
1 2 3
4 5 6
7 8 9
Avatar
esatarslan52 (Moderatör) #3
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Soruya göre 3x3 dizi sabit. Yani Matris sınıfından her nesne oluşturulduğunda satır ve sütün değerlerini girmesine gerek yok. Ama bu şekilde de olur tabi tercih senin.

Birde mDizi için hafızadan yer almayı aşağıdaki şekilde yapabilirsin.Seniki birazdaha C++ ca olmuş :)
float[][3] mDizi = new float[][3];

li-han:
örneğin float tipini 2 duyarlıklı gösteremedim. ayrıca (┐=191,└=192,│=179,┘=217,┌=218) karakterlerini ekrana basamadım.

    • 2 duyarlıklı float tipi için.printf() den kopya çekebilirsin.
    • (┐=191,└=192,│=179,┘=217,┌=218) karakterlerini ekrana basmak içinde Matris sınıfındaki dizi için hafızadan yer alırken yaptığın gibi tür dönüşümünden faydalanabilirsin.
Bu mesaj esatarslan52 tarafından değiştirildi; zaman: 2009-08-11, 04:17.
Mengu (Moderatör) #4
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
matrisleri bileydim yaparidim de, maalesef. :(
http://www.mengu.net - some kind of monster
Avatar
esatarslan52 (Moderatör) #5
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Mengu:
matrisleri bileydim yaparidim de, maalesef. :(
Sınıfın isminin Matris olduğuna bakma. Matris ismi almasının tek nedeni için de 3x3 bir matris dizi tanımlaması istenmesi sanırım. İşlevsel olarak Matrislerle pek alakası yok. Ağırlıklı olarak dizi işlemleri.
li-han #6
Üye Ağu 2009 tarihinden beri · 8 mesaj · Konum: Denizli
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
float[][3] dizi = new float[][3]; bunu bilmiyordum öğrendiğim iyi oldu.

şu şekilde kullanımda bi hata yok sanırım. yada doğru bi kullanımmı?
    float[][3] dizi = new float[][3];
    
    for (int i = 0; i < 3; ++i)
    {
        dizi[i].length = 3;
    }
    
    for (int i = 0; i < 3; ++i)
    {
        delete dizi[i];
    }
acehreli (Moderatör) #7
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ı
Aklıma hızlıca gelenler:

1) Birinci sorudaki geri vermeyle ilgili olarak: D'de çöp toplayıcı var ama scope anahtar sözcüğüyle nesnenin bir kapsamdan çıkılırken sonlanmasını da sağlayabiliyoruz.

2) Son kod daha kısa yazılabilir:

auto dizi = new float[][3];

Zaten bu tekrara C++'da başından beri gerek olmamalıydı. :) Sanırım yeni C++ standardı auto'nun bu kullanımını destekleyecek.

Ali
Avatar
esatarslan52 (Moderatör) #8
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sorunun Cevabı. Şurası şöyle olsa daha iyi olur dediğiniz yerler var mı?
import std.stdio;
import std.cstream;
import std.array;
 
class Matris
{
    private:
        float[3][3] mDizi;
 
    public:
        this()
        {
            mDizi = new float[3][3];
            mDizi = [[0,0,0],[0,0,0],[0,0,0]];
        }
        ~this()
        {
            writeln("Nesne Silindi...");
            delete mDizi[][];
        }
 
        version(Windows)
        {
            void yaz()
            {
                for (int i=0;i<3;i++)
                {
                    for (int j=0;j<3;j++)
                    {
                        // ┌ karaterin ekrana basar
                        if (i==0 && j ==0)
                            write(cast(char)218);
 
                        // │  karakterini ekrana basar
                        if (i==1 && j == 0)
                            write(cast(char)179);
 
                        // └ karakterini ekrana basar
                        if (i==2 && j == 0)
                            write(cast(char)192);
 
                        writef("%1.2f ",mDizi[i][j]);
 
                        // ┐ karakterini ekrana basar
                        if (i==0 && j ==2)
                            write(cast(char)191);
 
                        // │ karakterini ekrana basar
                        if (i==1 && j ==2)
                            write(cast(char)179);
 
                        // ┘ karakterini ekrana basar
                        if (i ==2 && j ==2)
                            write(cast(char)217);
                    }
                    writeln();
                }
            }
        }
        else version(linux)
        {
            void yaz()
            {
                for (int i=0;i<3;i++)
                {
                    for (int j=0;j<3;j++)
                        writef("%1.2f ",mDizi[i][j]);
 
                    writeln();
                }
            }
        }
 
        void diziDoldur()
        {
            float k=1.00;
            for (int i =0;i<3;i++)
            {
                for (int j=0;j<3;j++)
                {
                    mDizi[i][j] = k*1.00;
                    k++;
                }
            }
        }
 
        void dizidenAl(const float pDizi[][3])
        {
            for (int i =0;i<3;i++)
            {
                for (int j=0;j<3;j++)
                    mDizi[i][j] = pDizi[i][j];
            }
        }
 
        void diziyeDöndür(ref float pDizi[][3])
        {
            for (int i =0;i<3;i++)
            {
                for (int j=0;j<3;j++)
                    pDizi[i][j] = mDizi[i][j];
            }
        }
 
        void klavyedenAl()
        {
            for (int i =0;i<3;i++)
            {
                for (int j=0;j<3;j++)
                {
                    writef("mDizi[%d][%d]: ",i,j);
                    din.readf(&mDizi[i][j]);
                }
            }
        }
 
        Matris opAdd(Matris pToplanan)
        {
            Matris yedek = new Matris();
            for (int i =0;i<3;i++)
            {
                for (int j=0;j<3;j++)
                    yedek.mDizi[i][j] = mDizi[i][j] + pToplanan.mDizi[i][j];
            }
 
            return yedek;
        }
}
 
Matris nesneOluştur()
{
    Matris nesne = new Matris();
//    nesne.klavyedenAl();
    nesne.diziDoldur();
 
    return nesne;
}
 
char tuşAl()
{
    char tuş;
 
    do
    {
        din.read(tuş);
    } while(tuş == '\n');
 
    return tuş;
}
 
int main()
{
    char cevap;
    float[3][3] dizidenAl=[[10.00,11.00,12.00],[13.00,14.00,15.00],[16.00,17.00,18.00]];
    float[3][3] diziyeDöndür;
    Matris m1 = new Matris();
    Matris m2 = new Matris();
    Matris[] matrisDepo = new Matris[0];
 
    auto sonunaEkle = appender(&matrisDepo);
    sonunaEkle.put(nesneOluştur());
    do
    {
        if (cevap!='x')
            writeln("NesneEklendi...");
        write("Yeni Bir Nesne Oluşturmak İstermisiniz(E/H)?");
        cevap = tuşAl();
 
        switch(cevap)
        {
            case 'e','E':sonunaEkle.put(nesneOluştur());break;
            case 'h','H':break;
            default:writeln("Lütfen E veya H karakterlerinden birini seçin");
                    cevap='x';break;
        }
    }while(cevap =='e' || cevap =='E' || cevap =='x');
 
    foreach(yedek;matrisDepo)
        m2 = m2+yedek;
 
    writeln("\n===matrisDepo dizisine eklenen nesnelerin mDizi değişkenlerinin toplamı===");
    m2.yaz();
 
    return 0;
}
Bu mesaj esatarslan52 tarafından değiştirildi; zaman: 2009-08-15, 17:37.
acehreli (Moderatör) #9
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ı
Çok hızlı öğreniyorsun! :) Ben daha oralara gelemedim... Gerçekten! :) Programda değişiklikler yaptım ve yorumlarımı "[Ali]" ile belirttim:

import std.stdio;
import std.cstream;
import std.array;
 
class Matris
{
private:
    // [Ali] (Önemsiz bir konu) Ben duyarlığı çok düşük olduğu için
    // 'float'tan uzak durmayı tercih ediyorum. C++ olsa burada 'double'
    // kullanırdım ama D'de 'real' de olduğu için belki de kendim artık hep
    // 'real' kullanacağım
    float[3][3] mDizi;
 
public:
    this()
    {
        // [Ali] Sanırım new'e gerek yok; çünkü mDizi bir işaretçi
        // değil. Ek olarak, D'de dizilerin eleman türüne eşitlediğimiz
        // zaman bütün elemanlarının o değerle eşitlendiğini
        // öğrenmiştim. Sırf onu denemek için mDizi'nin ilk satırını
        // ilklemekle yetiniyorum. Çalıştı...
        mDizi = [0,0,0];
    }
 
    ~this()
    {
        writeln("Nesne Silindi...");
        // [Ali] Doğal olarak delete'e de gerek kalmıyor
    }
 
    // Ali: Burada Windows'la Linux'u ayırmamızın nedeni, herhalde Linux
    // ortamında kutu karakterlerinin olmamasıydı.
    //
    // Bence sorun o karakterlerin Linux'ta bulunmaması değil, Windows'da
    // kullanılan kod tablosuyla [code page] Linux'ta kullanılanın
    // birbirini tutmamasıydı. Ben o karakterleri açıklama satırlarından
    // çıkartıp kodların yerine yazıyorum... Benim ortamımda çalıştı! :)
    // (Kaynak kodun UTF-8 olmasının yararı... :)
    void yaz()
    {
        for (int i=0;i<3;i++)
        {
            for (int j=0;j<3;j++)
            {
                if (i==0 && j ==0)
                    write("┌");
 
                if (i==1 && j == 0)
                    write("│");
 
                if (i==2 && j == 0)
                    write("└");
 
                // [Ali] Bu format beni bayağı uğraştırdı. :) C'yi unutmaya
                // başlamışım. :D Virgülden önceki değer, bütün alanın
                // genişliği... Onun için %1.2f olmuyor
                writef("% 8.2f ",mDizi[i][j]);
 
                if (i==0 && j ==2)
                    write("┐");
 
                if (i==1 && j ==2)
                    write("│");
 
                if (i ==2 && j ==2)
                    write("┘");
            }
            writeln();
        }
    }
 
    void diziDoldur()
    {
        float k=1.00;
        for (int i =0;i<3;i++)
        {
            for (int j=0;j<3;j++)
            {
                mDizi[i][j] = k*1.00;
                k++;
            }
        }
    }
 
    // [Ali] Şart değil tabii ama 'in' ekledim ve derleyici 'const'a gerek
    // kalmadığını söyledi
    void dizidenAl(in float pDizi[][3])
    {
        for (int i =0;i<3;i++)
        {
            for (int j=0;j<3;j++)
                mDizi[i][j] = pDizi[i][j];
        }
    }
 
    // [Ali] Bana burada 'out' daha doğru geldi
    void diziyeDöndür(out float pDizi[][3])
    {
        for (int i =0;i<3;i++)
        {
            for (int j=0;j<3;j++)
                pDizi[i][j] = mDizi[i][j];
        }
    }
 
    void klavyedenAl()
    {
        for (int i =0;i<3;i++)
        {
            for (int j=0;j<3;j++)
            {
                writef("mDizi[%d][%d]: ",i,j);
                din.readf(&mDizi[i][j]);
            }
        }
    }
 
    Matris opAdd(Matris pToplanan)
    {
        Matris yedek = new Matris();
        for (int i =0;i<3;i++)
        {
            for (int j=0;j<3;j++)
                yedek.mDizi[i][j] = mDizi[i][j] + pToplanan.mDizi[i][j];
        }
 
        return yedek;
    }
}
 
Matris nesneOluştur()
{
    Matris nesne = new Matris();
    //    nesne.klavyedenAl();
    nesne.diziDoldur();
 
    return nesne;
}
 
char tuşAl()
{
    char tuş;
 
    do
    {
        din.read(tuş);
    } while(tuş == '\n');
 
    return tuş;
}
 
int main()
{
    char cevap;
    float[3][3] dizidenAl=[[10.00,11.00,12.00],[13.00,14.00,15.00],[16.00,17.00,18.00]];
    float[3][3] diziyeDöndür;
    Matris m1 = new Matris();
    Matris m2 = new Matris();
    Matris[] matrisDepo = new Matris[0];
 
    auto sonunaEkle = appender(&matrisDepo);
 
    // [Ali] Burada etiketli döngü olanağını denemek istedim. Yine de,
    // bence içerde E/H bekleyen döngüyü başka bir fonksiyona taşımak bence
    // daha doğru olur:
    //
    //   cevap = evet_hayır_al("Yeni bir nesne oluşturmak ister misiniz");
    //
    // O fonksiyon başka karakterleri süzer ve örneğin küçük harf olarak ya
    // 'e' ya da 'h' döndürebilir. Sonra:
    //
    //   if (cevap == 'h') break;
    //
    // veya önceki gibi bir do-while kullanılır ve 'cevap' sonunda denetlenir.
    //
nesne_ekle:
    while (true)
    {
        // [Ali] Bu satırı içeriye aldım
        sonunaEkle.put(nesneOluştur());
 
        // [Ali] Bunu yazdırırken 'x' karşılaştırmasına gerek kalmadı
        writeln("NesneEklendi...");
 
        while (true) {
            write("Yeni bir nesne oluşturmak ister misiniz(E/H)? ");
            cevap = tuşAl();
 
            switch(cevap)
            {
            case 'e','E':
                // [Ali] Etiketler sayesinde iç döngüden dış döngüye devam
                // edebiliyoruz
                continue nesne_ekle;
 
            case 'h','H':
                // [Ali] Burada da...
                break nesne_ekle;
 
            default:
                writeln("Lütfen E veya H karakterlerinden birini seçin");
                break;
            }
        }
 
    }
    // [Ali] Burada do-while'ın sonundaki 'e', 'E', ve 'x'
    // karşılaştırmalarına gerek kalmadı
 
    // [Ali] Ben her zaman küme parantezleri kullanırım :)
    foreach(yedek;matrisDepo) {
        m2 = m2+yedek;
    }
    
    writeln("\n===matrisDepo dizisine eklenen nesnelerin mDizi değişkenlerinin toplamı===");
    m2.yaz();
 
    return 0;
}

Ali
Avatar
esatarslan52 (Moderatör) #10
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Fikirleriniz için teşekkürler :)
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-23, 23:20:36 (UTC -08:00)