2013-06-10 27 views
7

Qual è il modo migliore di scrivere una struttura di controllo che eseguirà una iterazione attraverso ciascuna combinazione di 2 elementi in una lista?Confronto di ogni elemento con ogni altro elemento in una lista

Esempio:

{0,1,2} 

voglio avere un blocco di codice di esecuzione tre volte, una volta su ciascuno di questi:

{0,1} 
{1,2} 
{0,2} 

ho provato il seguente

foreach (int i in input) 
{ 
    foreach (int j in input.Where(o => o != i)) 
    { 
     //Execute code 
    } 
} 

Tuttavia , questo non funzionerà quando una lista ha due degli stessi elementi. Con

{0,2,0} 

avrei ancora voglia di confrontare gli elementi 0 e 0. Il valore è irrilevante.

+1

Cosa stai facendo con ciascuna di queste coppie? La tua soluzione e le soluzioni di Jon sono tutte O (n al quadrato). A seconda di ciò che stai facendo, potrebbe esserci una soluzione O (n). (Ad esempio, nel compilatore C# è necessario confrontare ogni coppia di metodi in un problema di risoluzione di sovraccarico per determinare il metodo migliore unico: esiste un algoritmo O (n) anche se la relazione migliore è intransitiva.) –

risposta

21

Sembra che si potrebbe desiderare qualcosa di simile:

for (int i = 0; i < list.Count - 1; i++) 
{ 
    for (int j = i + 1; j < list.Count; j++) 
    { 
     // Use list[i] and list[j] 
    } 
} 

È sicuramente possibile farlo con LINQ:

var pairs = from i in Enumerable.Range(0, list.Count - 1) 
      from j in Enumerable.Range(i + 1, list.Count - i) 
      select Tuple.Create(list[i], list[j]); 

io non sono sicuro che sia più chiaro anche se ...

MODIFICA: Un'altra alternativa meno efficiente, ma potenzialmente più chiara:

var pairs = from i in Enumerable.Range(0, list.Count - 1) 
      let x = list[i] 
      from y in list.Skip(i + 1) 
      select Tuple.Create(x, y); 
+0

Perfetto, molto più semplice di quanto immaginassi. Accetterò quando possibile. E grazie, ma hai ragione, la soluzione LINQ è molto meno leggibile e molto probabilmente molto più lenta. – Wilson

Problemi correlati