Thread overview
cartesianProduct metodu kullanımı
Nov 10, 2016
zafer
Nov 15, 2016
zafer
Dec 12, 2016
zafer
November 10, 2016

Merhaba,

Ürün varyantı oluşturmak için araştırmalar yaparken std.algorithm.setops modülünde bulunan cartesianProduct (https://dlang.org/phobos/std_algorithm_setops.html#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?

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

November 12, 2016

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

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

November 15, 2016

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.

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

December 12, 2016

Aynı soru İngilizce forumda soruldu ve şöyle bir aralık çözümü verildi:

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

Ali

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

December 12, 2016

Ali çok teşekkürler :) Kesinlikle çok işime yarayacak özellikle foreach ile kullanımı işlerimi çok kolaylaştıracak.

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