SORU
22 HAZİRAN 2010, Salı


Üreten tüm Olası Kombinasyonları

2 diziler = Dizi1 {a,b,c...n} verilen ve = Array2 {10,20,15....x} ..
nasıl Dize olarak tüm olası kombinasyon oluşturabilirsiniz(i) (j) b c(k) n(p)
nerede ;= 20 , 1 < j <= 10, 1 < 1 <=;=;= k <= 15, .... 1 < p <= x

gibi


c1 ...a1 b1. n1
c1....a1 b1. n2
......
......
a10 b20 c15 nx (son birleşimi)


Arada toplam sayısı = array2 unsurları ürün = çok (10 X 20 X 15 X X ..x) dizeleri .

EDİT
İkinci dizinin her öğesi için üst sınırı tanımlar kartezyen ürün benzer ilk dizi.

EDİT

Sabit bir sayı ile örneğin

    Array x =  [a,b,c]
    Array y =  [3,2,4] 

2 = **4 3 24 kombinasyon olacak

dizeleri olarak alıyoruz

    a1 b1 c1  
    a1 b1 c2  
    a1 b1 c3  
    a1 b1 c4  

    a1 b2 c1  
    a1 b2 c2  
    a1 b2 c3  
    a1 b2 c4


    a2 b1 c1  
    a2 b1 c2  
    a2 b1 c3  
    a2 b1 c4  

    a2 b2 c1  
    a2 b2 c2  
    a2 b2 c3  
    a2 b2 c4


    a3 b1 c1  
    a3 b1 c2  
    a3 b1 c3  
    a3 b1 c4  

    a3 b2 c1  
    a3 b2 c2  
    a3 b2 c3  
    a3 b2 c4 (last)

    ---------

C kullanıyorum# .

Edit: topluluk Wiki 29/10/2010

CEVAP
23 HAZİRAN 2010, ÇARŞAMBA


Elbette. SERİ ile bunu yapmak biraz zor ama, imkansız sadece standart sorgu operatörleri kullanıyor.

GÜNCELLEME: Bu my blog on Monday June 28th 2010; harika soru için teşekkür ederim konusudur. Ayrıca, blogumda bir yorumcu verdim olandan bile daha şık bir sorgu olduğunu kaydetti. Kodu burada kullanmak için güncelleriz.

Zor kısmı keyfi olarak birçok dizileri Kartezyen çarpımı. "Sıkıştırma" harfleri ile karşılaştırıldığında önemsiz. Bu nasıl çalıştığını anlamak emin olmak için çalışması gerekir. Her bölüm yeterince basit, ama birlikte kombine şekilde alışmak biraz zaman alır:

    static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>()};
        return sequences.Aggregate(
            emptyProduct,
            (accumulator, sequence) => 
                from accseq in accumulator 
                from item in sequence 
                select accseq.Concat(new[] {item})                          
            );
     }

Bu nasıl çalıştığını açıklamak için, ilk "operasyon yapıyor. birikir ne olduğunu anlamak Basit bir işlemdir birikir "bu sırada her şeyi birlikte ekleyin". Bu şekilde yapman: sıfır ile başlar. Sırayla her madde için akünün akım değeri akü öğesi ve bir önceki değeri toplamına eşittir. Aynı şeyi yapıyoruz, toplamı toplamı şimdiye kadar dayalı ve geçerli madde birikimi yerine, Kartezyen çarpımı birleştiriyoruz.

Bunu yapmak için gittiğimiz yolda biz zaten iki şeyden Kartezyen çarpımı hesaplar SERİ bir operatör olduğu gerçeğini yararlanmak için:

from x in xs
from y in ys
do something with each possible (x, y)

Tekrar tekrar giriş sırayla bir sonraki madde ile akümülatör Kartezyen ürün alarak ve sonuçları birlikte küçük bir yapıştırma yaparak, Kartezyen çarpımı oluşturabiliriz.

Düşün akümülatör değeri. Görsel amaçlı olarak akümülatör değerini göstereceğimsonuçlarısıra operatörleri içerir. Bu akü ne değildiraslındaiçerir. Akümülatör aslında ne içerdiğinioperatörlerbu sonuçlar. Bütün işlem burada sadece bir artıyorbüyüksonuç Kartezyen çarpımı sıra operatörleri, ağaç. Amason Kartezyen ürünün kendisi sorgu yürütülür kadar aslında değil hesaplanır.Açıklayıcı amaçlar için ne göstereceğimsonuçlarıyolun her aşamasında ama unutmayın, bu aslında içeriroperatörlerbu sonuçlar.

Dizileri dizisi {{1, 2}, {3, 4}, {5, 6}} Kartezyen ürün alıyoruz sanırım. Bir sıra boş bir sıra içeren başlıyor akümülatör: { { } }

İlk birikim, akümülatör { { } } ve item {1, 2}. Bizim işimiz bu:

                from accseq in accumulator
                from item in sequence 
                select accseq.Concat(new[] {item})

Yani biz alarak Kartezyen çarpımı { { } } {1, 2} ve her bir çift, biz bir arada: var çifti ({ }, 1), bu yüzden biz bir arada { } {1} {1}. { } {2} {2} biz bir arada çok çifti ({ }, 2}) var. Bu yüzden sonuç olarak {{1}, {2}} var.

İkinci birikimi kadar, akümülatör {{1}, {2}} ve Madde {3, 4}. Yine, biz bu iki sıraları Kartezyen ürün almak için hesaplamak:

 {({1}, 3), ({1}, 4), ({2}, 3), ({2}, 4)}

ve daha sonra bu öğeler, ilk üzerine ikinci bir arada. Sonuç bu sıra tam da bizim istediğimiz gibi {{1, 3}, {1, 4}, {2, 3}, {2, 4}},.

Şimdi tekrar birikir. {5, 6} ile akümülatör Kartezyen ürün almak için alıyoruz

 {({ 1, 3}, 5), ({1, 3}, 6), ({1, 4}, 5), ...

ve sonra ilk üzerine ikinci öğeyi bir arada:

{{1, 3, 5}, {1, 3, 6}, {1, 4, 5}, {1, 4, 6} ... }

ve işimiz bitti. Kartezyen çarpımı birikmiş ettik.

Keyfi olarak birçok dizileri Kartezyen çarpımı alabilir yarar bir işlevi var artık, gerisi basit bir karşılaştırma

        var arr1 = new[] {"a", "b", "c"};
        var arr2 = new[] { 3, 2, 4 };
        var result = from cpLine in CartesianProduct(
                         from count in arr2 select Enumerable.Range(1, count)) 
                     select cpLine.Zip(arr1, (x1, x2) => x2   x1);

Ve şimdi her satıra dizeler, diziler, dizeleri bir dizi bir dizi var:

        foreach (var line in result)
        {
            foreach (var s in line)
                Console.Write(s);
            Console.WriteLine();
        }

Çok kolay!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • o0oCyrusViruso0o

    o0oCyrusViru

    11 Mart 2008
  • Unbox Therapy

    Unbox Therap

    21 Aralık 2010
  • Willie D.

    Willie D.

    16 Aralık 2006