2010-02-25 15 views
7

Eine grundlegende Lösung würde wie folgt aussehen:Finding, wenn eine Zielnummer die Summe von zwei Zahlen in einem Array über LINQ ist

bool sortTest(int[] numbers, int target) 
{ 
    Array.Sort(numbers); 
    for(int i = 0; i < numbers.Length; i++) 
    { 
     for(int j = numbers.Length-1; j > i; j--) 
     { 
      if(numbers[i] + numbers[j] == target) 
       return true; 
     } 
    } 
    return false; 
} 

Jetzt ganz neu Ich bin zu LINQ, aber das ist das, was ich geschrieben habe, so weit:

var result = from num in numbers 
      where numbers.Contains(target -num) 
      select num; 
if (result.Count() > 0) 
    return true; 

return false; 

Jetzt renne ich in ein Problem das folgende Beispiel gegeben:
Array: 1, 2, 4, 5, 8
Ziel: 16

Es sollte false zurückgeben, aber es fängt 16-8 = 8. Also, wie gehe ich davon aus, dass es sich im contains check nicht merkt? Oder kann ich jedes Mal ein zweites Array innerhalb der Abfrage erstellen, das nicht die Nummer enthält, mit der ich arbeite (wodurch das Problem gelöst wird)?

Vielen Dank im Voraus.

Antwort

5

Ist das wonach Sie suchen?

var result = from n1 in numbers 
      from n2 in numbers 
      where n1 != n2 && n1 + n2 == target 
      select new { n1, n2 }; 

[Bearbeiten] Dies gibt Spiele zweimal und ignoriert die Situation, in der eine Zahl im Array dupliziert. Sie können diese Situationen mit Expression Syntax behandeln, weil Sie nicht den Index eines angepassten Element zugreifen können, aber Sie können es tun, wie folgt:

var result = numbers.Select((n1, idx) => 
    new {n1, n2 = numbers.Take(idx).FirstOrDefault(
    n2 => n1 + n2 == target)}).Where(pair => pair.n2 != 0); 

Solange Sie haben noch keine Nullen in Ihrem Array.

[Weitere Gedanken Bearbeiten]

Die perfekte Mischung Lösung:

var result = from item in numbers.Select((n1, idx) => 
       new {n1, shortList = numbers.Take(idx)}) 
      from n2 in item.shortList 
      where item.n1 + n2 == target 
      select new {n1 = item.n1, n2}; 
+0

Nizza :) Sie scheinen viel wacher als ich heute Morgen +1 – leppie

+0

Eine Sache: Was passiert, wenn das Array zwei Zahlen enthält, die gleich sind und mit dem Ziel aufsummieren würde? Ex: Das Array enthielt 2 8 ist und das Ziel war 16. Anders als das war Ihre Aussage super und half mir sehr viel. –

+0

Ja, es gibt auch jedes passendes Paar zweimal: das heißt. 4 + 8 = 12; 8 + 4 = 12. Ich bin nur eine noch bessere Antwort, um herauszufinden,. – pdr

1

auf pdr Antwort zu verbessern und die Bedenken in den Kommentaren erwähnt Adresse, die Sie die overloaded Select method verwenden könnten die Indizes der Elemente vergleichen und stellen Sie Einzigartigkeit sicher.

public bool sortTest(int[] numbers, int target) 
{ 
    var indexedInput = numbers.Select((n, i) => new { Number = n, Index = i }); 

    var result = from x in indexedInput 
       from y in indexedInput 
       where x.Index != y.Index 
       select x.Number + y.Number == target; 

    return result.Any(item => item); 
} 

Oder in Punktnotation:

var result = numbers.Select((n, i) => new { Number = n, Index = i }) 
        .SelectMany(
         x => indexedInput, 
         (x, y) => new { x = x, y = y }) 
        .Where(item => item.x.Index != item.y.Index) 
        .Select(item => item.x.Number + item.y.Number == target); 
4

Was ich dieses Problem im Allgemeinen zu lösen tun würde schreiben wird zuerst einen "Chooser".

public static IEnumerable<IEnumerable<T>> Chooser<T>(this IList<T> sequence, int num) 
{ ... left as an exercise ... } 

Die Ausgabe des Choosers ist eine Folge von Sequenzen. Jede Untersequenz hat die Länge num und besteht aus Elementen, die aus der ursprünglichen Sequenz ausgewählt sind. Also, wenn Sie übergeben {10, 30, 20, 50} als Sequenz und 3 für num, dann würden Sie die Reihenfolge der Sequenzen erhalten:

{10, 30, 20}, {10, 30, 50}, {10, 20, 50}, {30, 20, 50} 

als Ergebnis.

Sobald Sie Chooser geschrieben haben, wird das Problem einfach:

var results = 
    from subsequence in numbers.Chooser(2) 
    where subsequence.Sum() == target 
    select subsequence; 

Und jetzt können Sie das Problem für Teilfolgen anderer Größen lösen, nicht nur Paare.

Writing Chooser ist ein bisschen schwierig, aber es ist nicht zu hart.

Verwandte Themen