2010-04-10 25 views
2

您好,我是Linq的新手,我发现这个线程可以解释我需要的90% https://stackoverflow.com/questions/2331882?tab=newest#tab-top,感谢“pdr”寻找一个目标数字是通过LINQ得到的数组中的两个数字的总和,并获得和索引

,但我需要的是让指数过,这是我修改我得到的第一个数字的索引,但我不知道如何获得的第二个数字

  int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
     var result = from item in numbers.Select((n1, idx) => 
      new { n1,idx, shortList = numbers.Take(idx) }) 
        from n2 in item.shortList 
        where item.n1 + n2 == 7 
        select new { nx1 = item.n1,index1=item.idx, nx2=n2 }; 

回答

3

SelectMany is你需要什么...

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
int target = 7; 

var query = numbers 
       .SelectMany((num1,j) => numbers.Select((num2,i) => new {n1=num1, n2=num2, i=i, j=j})) 
       .Where(x => x.n1 + x.n2 == target && x.i < x.j); 

foreach (var x in query)   
    Console.WriteLine(x.n1 + " and " + x.n2 + " occur at " + x.i + "," + x.j); 
+0

这当然是O(n平方)。有一个O(n)算法来解决这个问题(如果它们是排序的话) - 本质上是跨矩阵的对角走向 - 但是在LINQ中以纯功能方式实现它需要非常巧妙地使用Aggregate()。 – 2010-04-11 09:02:18

+0

非常感谢Linq是如此的强大,你有什么建议来掌握它。 – 2010-04-12 01:08:04

+0

这听起来像一个新问题:-)关于掌握它的建议... 1.经常使用它; 2.看看每个foreach循环,看看它在LINQ中是否更清晰/更容易表达; 3.按照StackOverflow上的LINQ标签查看所有人问的问题和“正确”的答案。 – 2010-04-12 06:47:38

1

该指数会给你一对项目,每个项目都包含来自数组及其索引的值。这些对被限制在值的总和等于目标的地方。 Where子句中的& &消除重复项和自我匹配(适用于偶数目标)。

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

int target = 7; 

var query = from item1 in numbers.Select((number, index) => new { Number = number, Index = index }) 
      from item2 in numbers.Select((number, index) => new { Number = number, Index = index }) 
      where item1.Number + item2.Number == target 
      && item1.Index < item2.Index 
      select new { Item1 = item1, Item2 = item2 }; 

foreach (var itemPair in query) 
{ 
    Console.WriteLine("{0}:{1}\t{2}:{3}", 
     itemPair.Item1.Index, 
     itemPair.Item1.Number, 
     itemPair.Item2.Index, 
     itemPair.Item2.Number); 
} 
0

如果它绝对超过一个阵列那么你可以这样做:

var result = from index1 in Enumerable.Range(0, numbers.Length) 
      from index2 in Enumerable.Range(index1 + 1, 
              numbers.Length - index - 1) 
      where numbers[index1] + numbers[index2] == targetNumber 
      select new { index1, index2, 
          value1 = numbers[index1], value2 = numbers[index2] }; 

否则,您可以使用Select形式包括指数两次:

var result = from pair1 in numbers.Select((value, index) => new { value, index}) 
      from pair2 in numbers.Skip(pair1.index + 1) 
            .Select((value, index) => 
            new { value, index = index - pair2.index - 1}) 
      where pair1.value + pair2.value == targetNumber 
      select new { index1 = pair1.index, index2 = pair2.index, 
          value1 = pair1.value, value2 = pair2.value }; 

两个这些真的很难看......

+0

我发现这些代码片段都没有在他原来的数组和目标上返回预期的结果。第一个抛出一个'IndexOutOfRangeException',而第二个不返回正确的索引。这两个片段都不会返回元素值以跟随索引。 – 2010-04-11 04:54:05

+0

@Anthony:糟糕 - 将解决这两个问题。获取元素值也非常容易。 – 2010-04-11 06:59:08

相关问题