Forum: D Programlama Dili RSS
cartesianProduct metodu kullanımı
zafer #1
Üye Tem 2009 tarihinden beri · 687 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: cartesianProduct metodu kullanımı
Merhaba,

Ürün varyantı oluşturmak için araştırmalar yaparken std.algorithm.setops modülünde bulunan cartesianProduct metoduna rastladım. Gayet güzel çalışıyor ve tam istediğimi yapıyor.

Ancak çalışma zamanında bu metoda belirsiz sayıda dizi gönderimini nasıl yapabilirim bulamadım?
https://github.com/zafer06 - depo
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4389 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Derleme zamanında örneğin int, string, double elemanlı 3 dizi varsa sonucun Tuple!(int, string, double) olduğu bilinebiliyor ve kod o biçimde derleniyor. Ama dizi (tabii, daha doğru olara herhangi bir aralık türü) sayısı baştan bilinmeyince sonucun türü de bilinemiyor.

Bütün dizilerin eleman türleri aynı olduğunda cartesianProduct'ın türünü bir dizi olarak gösterebiliriz. Örneğin, int elemanlı üç dizi çarpıldığında her eleman 3 uzunluklu int[] olabilir:
import std.stdio;
import std.algorithm;
import std.range;
 
auto cartesianProductDynamic(R)(R[] aralıklar) {
    assert(!aralıklar.empty);
 
    switch (aralıklar.length) {
    case 1:
        // Tek dizinin cartesianProduct'ı kendisidir
        return aralıklar;
        break;
    case 2:
        // Phobos'unkini çağırıyoruz ama elemanları Tuple'dan dilime dönüştürüyoruz
        return cartesianProduct(aralıklar[0], aralıklar[1]).map!(t => t.array).array;
        break;
    default:
        // Yine Phobos'unkini çağırıyoruz ama elemanları Tuple'dan dilime dönüştürüyoruz
        return cartesianProduct(aralıklar[0], cartesianProductDynamic(aralıklar[1..$]))
                   .map!(t => t[0] ~ t[1]).array;
        break;
    }
}
 
void main() {
    auto a = [ 1, 2 ];
    auto b = [ 33, 44 ];
    auto c = [ 555, 666, 777 ];
 
    // Kaç adet oldukları derleme zamanında bilinmeyen aralıklar. (Tabii bu durumda 3 ama olsun.)
    auto aralıklar = [ a, b, c ];
 
    auto sonuç = cartesianProductDynamic(aralıklar);
    writefln("%(%s\n%)", sonuç);
}

[1, 33, 555]
[1, 33, 666]
[1, 33, 777]
[1, 44, 555]
[1, 44, 666]
[1, 44, 777]
[2, 33, 555]
[2, 33, 666]
[2, 33, 777]
[2, 44, 555]
[2, 44, 666]
[2, 44, 777]

Derlenebilmesi için bir sürü .array kullanmak zorunda kaldım; performans sorunu oluşturabilirler.

Elemanlar aynı olmadıklarında Variant'tan yararlanmak gerekecektir. O zaman sonucun her elemanı bir Variant dizisi olur.

Ali
zafer #3
Üye Tem 2009 tarihinden beri · 687 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali harikasın! Şu özyinelemeli işlevler gerçekten çok güçlü ama ben halen tam olarak anlayamadım.

Performans konusunda sıkıntı yaşamam diye düşünüyorum. Bu işlem sadece ürün girişi yapılırken kullanılacak bunun dışında bu işleme ihtiyaç olmayacak, bu sebeple bu haliyle işimi görür diye düşünüyorum.

Kodu ilk denediğimde bana "Warning: statement is not reachable" uyarısını verdi. Bende case bloklarının sonundaki "break;" ifadesini kaldırdım. Bunun dışında gayet güzel çalışıyor :) Tekrardan teşekkürler.
https://github.com/zafer06 - depo
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4389 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Aynı soru İngilizce forumda soruldu ve şöyle bir aralık çözümü verildi:

  http://forum.dlang.org/post/leugranlzvwcdizvmagf@forum.dla…

Ali
zafer #5
Üye Tem 2009 tarihinden beri · 687 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali çok teşekkürler :) Kesinlikle çok işime yarayacak özellikle foreach ile kullanımı işlerimi çok kolaylaştıracak.
https://github.com/zafer06 - depo
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-03-23, 11:23:48 (UTC -07:00)