2010-02-25 12 views
7

Una solución básica se vería así:si un número de destino es la suma de dos números en una matriz a través de LINQ

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; 
} 

Ahora estoy muy nuevo en LINQ pero esto es lo que he escrito hasta ahora:

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

return false; 

Ahora estoy corriendo en un problema dado el ejemplo siguiente:
matriz: 1, 2, 4, 5, 8
Target: 16

Debería volver falso, pero está atrapando 16-8 = 8. Entonces, ¿cómo hago para no dejar que se note en el cheque contiene? ¿O puedo hacer una segunda matriz cada vez dentro de la consulta que no contenga el número con el que estoy trabajando (resolviendo así el problema)?

Gracias de antemano.

Respuesta

5

¿Esto es lo que estás buscando?

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

[Editar] Esto devuelve partidos dos veces e ignora la situación en la que un número se duplica en la matriz. No se puede manejar estas situaciones utilizando la sintaxis de expresiones porque no se puede acceder al índice de un elemento coincidente, pero se puede hacer así:

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

Mientras que usted no tiene ningún cero en su formación.

[más Editar pensamiento]

La solución mezcla perfecta:

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

Bonito :) Pareces mucho más despierto que yo esta mañana +1 – leppie

+0

Una cosa: ¿Qué pasa si la matriz contiene dos números que son iguales y se sumarían al objetivo? Ej: La matriz contenía 2 8 y el objetivo era 16. Aparte de eso, tu declaración fue increíble y me ayudó mucho. –

+0

Sí, también devuelve cualquier par coincidente dos veces: es decir. 4 + 8 = 12; 8 + 4 = 12. Solo estoy tratando de encontrar una respuesta aún mejor. – pdr

1

Para mejorar la respuesta del PDR y abordar las preocupaciones mencionadas en los comentarios se podría utilizar el overloaded Select method para comparar los índices de los artículos y asegurar la singularidad.

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

O en notación de puntos:

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

lo que he hecho para resolver este problema, en general, primero se escribe un "selector".

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

La salida del selector es una secuencia de secuencias. Cada subsecuencia es de longitud num, y consiste en elementos elegidos de la secuencia original. Así que si usted pasó {10, 30, 20, 50} como la secuencia y 3 para num, se obtendría la secuencia de las secuencias:

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

como resultado.

vez que haya escrito Selector, el problema se convierte en fácil:

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

y ahora se puede resolver el problema de las subsecuencias de otros tamaños, no sólo los pares.

Escribir Selector es un poco complicado pero no es demasiado difícil.

Cuestiones relacionadas