2010-07-23 24 views
17

che sto cercando un modo efficace per raggiungere questo obiettivo:Ottenere tutte le combinazioni possibili da un elenco di numeri

  • si dispone di un elenco di numeri 1 ..... n (tipicamente: 1 .. 5 o 1..7 circa - ragionevolmente piccolo, ma può variare da caso a caso)

  • occorrono tutte le combinazioni di tutte le lunghezze per tali numeri, ad es. tutte le combinazioni di un solo numero ({1}, {2}, .... {n}), quindi tutte le combinazioni di due numeri distinti ({1,2}, {1,3}, {1,4}. .... {n-1, n}), allora tutte le combinazioni di fo tre di questi numeri ({1,2,3}, {1,2,4}) e così via

Fondamentalmente, all'interno del gruppo, l'ordine è irrilevante, quindi {1,2,3} equivale a {1,3,2} - è solo questione di ottenere tutti i gruppi di x numeri da quella lista

Sembra che ci dovrebbe essere un semplice algoritmo per questo - ma ho cercato invano finora. La maggior parte degli algoritmi di combinatoria e permutazione sembra a) prendere in considerazione l'ordine (ad esempio 123 non è uguale a 132), e sembra sempre operare su una singola stringa di caratteri o numeri ....

Chiunque ha un grande, bel'n'quick algoritmo nella loro manica ??

Grazie!

+2

Si sono fondamentalmente cercando il [Power Set] (http://en.wikipedia.org/wiki/Power_set) di la tua lista (che è matematicamente un set, se tutti i suoi articoli sono unici). –

+0

Vedi anche qui: https://stackoverflow.com/questions/7802822/all-possibili-combinazioni-di-una-qualità-di-valori/41642733#41642733 – RenniePet

risposta

38

Basta incrementare un numero binario e prendere gli elementi corrispondenti ai bit impostati.

Per esempio, 00101101 significherebbe prendere gli elementi a indici 0, 2, 3 e 5. Dal momento che l'elenco è semplicemente 1..n, l'elemento è semplicemente l'indice di + 1.

Questo genererà permuatazioni in corso. In altre parole, verrà generato solo {1, 2, 3}. Non o {2, 1, 3} o {2, 1, 3} o {2, 3, 1}, ecc.

+0

@ La soluzione di Henri è praticamente una implementazione di questa idea, usando LINQ. –

+0

@Nate Kohl Sì, ho appena commentato. Abbastanza intelligente! Ha dato un +1. – jdmichal

+0

+1: una bella prova che il numero di sottoinsiemi di un determinato set di dimensioni N è 2^N –

9

Questo è qualcosa che ho scritto in passato per svolgere tale compito.

List<T[]> CreateSubsets<T>(T[] originalArray) 
{ 
    List<T[]> subsets = new List<T[]>(); 

    for (int i = 0; i < originalArray.Length; i++) 
    { 
     int subsetCount = subsets.Count; 
     subsets.Add(new T[] { originalArray[i] }); 

     for (int j = 0; j < subsetCount; j++) 
     { 
      T[] newSubset = new T[subsets[j].Length + 1]; 
      subsets[j].CopyTo(newSubset, 0); 
      newSubset[newSubset.Length - 1] = originalArray[i]; 
      subsets.Add(newSubset); 
     } 
    } 

    return subsets; 
} 

E 'generica, in modo da funzionare per interi, long, stringhe, Foos, ecc

+3

come usiamo questo? – MonsterMMORPG

31

Non è il mio codice, ma si sta cercando il Powerset. Google mi ha dato questa soluzione, che sembra t lavoro:

public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list) 
{ 
    return from m in Enumerable.Range(0, 1 << list.Count) 
       select 
        from i in Enumerable.Range(0, list.Count) 
        where (m & (1 << i)) != 0 
        select list[i]; 
} 

Fonte: http://rosettacode.org/wiki/Power_set#C.23

+3

Solo per chiarimenti, questa è la mia risposta, implementata tramite LINQ. Che, devo ammettere, è abbastanza intelligente. – jdmichal

+0

Sì, è :) Mi è piaciuta la soluzione, da qui il codice! – Henri

+2

Power Of Linq, un momento di rispetto per questo. – Rev

Problemi correlati