2013-06-10 25 views
7

Wie schreibt man am besten eine Kontrollstruktur, die durch jede 2-Elemente-Kombination in einer Liste iteriert?Vergleichen jedes Elements mit jedem anderen Element in einer Liste

Beispiel:

{0,1,2} 

ich einen Code-Block laufen dreimal haben wollen, einmal auf jedem dieser:

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

habe ich versucht, die folgende

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

jedoch Dies funktioniert nicht, wenn eine Liste zwei gleiche Elemente enthält. Mit

{0,2,0} 

mag ich noch auf den Elemente 0 und 0 vergleichen. Der Wert ist irrelevant.

+1

Was machst du mit jedem dieser Paare? Ihre Lösung und Jons Lösungen sind alle O (n Quadrat). Je nachdem, was Sie tun, könnte es eine O (n) -Lösung geben. (Zum Beispiel müssen Sie im C# -Compiler jedes Methodenpaar in einem Überladungsauflösungsproblem vergleichen, um die eindeutige beste Methode zu bestimmen; dafür gibt es einen O (n) -Algorithmus, obwohl die bessere Methodenbeziehung intransitiv ist.) –

Antwort

21

Es klingt wie Sie so etwas wie wollen könnte:

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

Sie auf jeden Fall kann dies mit LINQ tun:

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]); 

Ich bin nicht sicher, es ist jeder obwohl klarer ...

EDIT: Eine andere Alternative, die weniger effizient, aber möglicherweise klarer ist:

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

Perfekt, viel einfacher als ich es mir vorgestellt habe. Ich werde akzeptieren, wenn möglich. Und danke, aber Sie haben Recht, die LINQ-Lösung ist viel weniger lesbar und wahrscheinlich viel langsamer. – Wilson

Verwandte Themen