简体   繁体   English

通过LINQ查找目标编号是否是数组中两个数字的总和

[英]Finding if a target number is the sum of two numbers in an array via LINQ

A basic solution would look like this: 基本解决方案如下所示:

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

Now I'm very new to LINQ but this is what I have written so far: 现在我对LINQ很新,但这是我到目前为止写的:

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

return false;

Now i'm running into an issue given the following example: 现在我遇到以下示例遇到的问题:
Array: 1, 2, 4, 5, 8 数组:1,2,4,5,8
Target: 16 目标:16

It should return back false, but it's catching 16-8=8. 它应该返回false,但它正在捕获16-8 = 8。 So how do I go about not letting it notice itself in the contains check? 那么我怎么去不让它在包含检查中注意到它? Or can I make a second array each time within the query that doesn't contain the number I'm working with(thus solving the problem)? 或者我可以在查询中每次创建第二个数组,但不包含我正在使用的数字(从而解决问题)?

Thanks in advance. 提前致谢。

Is this what you're looking for? 这是你在找什么?

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

[Edit] This returns matches twice and ignores the situation where a number is duplicated in the array. [编辑]这将返回两次匹配,并忽略数组在数组中重复的情况。 You can't handle these situations using Expression Syntax because you can't access the index of a matched item, but you can do it like this: 您无法使用表达式语法处理这些情况,因为您无法访问匹配项的索引,但您可以这样做:

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

As long as you don't have any zeros in your array. 只要你的数组中没有任何零。

[Further thought Edit] [进一步思考编辑]

The perfect mix solution: 完美的混合解决方案:

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

What I'd do to solve this problem in general is first write a "chooser". 我一般要解决这个问题,首先要写一个“选择器”。

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

The output of the chooser is a sequence of sequences. 选择器的输出是一系列序列。 Each sub-sequence is of length num, and consists of elements chosen from the original sequence. 每个子序列的长度为num,由选自原始序列的元素组成。 So if you passed { 10, 30, 20, 50 } as the sequence and 3 for num, you'd get the sequence of sequences: 因此,如果您通过{10,30,20,50}作为序列而3作为num,您将获得序列序列:

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

as a result. 结果是。

Once you've written Chooser, the problem becomes easy: 一旦你编写了Chooser,问题就变得容易了:

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

And now you can solve the problem for subsequences of other sizes, not just pairs. 现在你可以解决其他尺寸的子序列的问题,而不仅仅是对。

Writing Chooser is a bit tricky but it's not too hard. 写选配是有点棘手,但它不是太难

To improve on pdr's reply and address the concerns mentioned in the comments you could use the overloaded Select method to compare the indices of the items and ensure uniqueness. 为了改进pdr的回复并解决注释中提到的问题,您可以使用重载的Select方法来比较项的索引并确保唯一性。

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

Or in dot notation: 或者用点符号表示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM