简体   繁体   English

在列表C#中查找下一个最高和最低的数字

[英]Find next highest and next lowest number in list c#

I have a list of numbers and if the number that I am looking for is not in the list I want to be able to find the next value that is in the list above and below the number that I have asked for. 我有一个数字列表,如果我要查找的数字不在列表中,我希望能够找到我要的数字上方和下方的列表中的下一个值。

double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
//do code to find next highest/lowest
double higher = 7;
double lower = 3;

for example, because 5 is not exactly in the list itself I want it to return the next item that is closest to 5 both above and below. 例如,因为5本身不在列表中,所以我希望它返回上下两个都最接近5的下一个项目。 so for this case, 3 and 7. 所以在这种情况下3和7

Original version 原始版本

You can use List's Sort() method, then use LINQ FirstOrDefault() and LastOrDefault() 您可以使用List的Sort()方法,然后使用LINQ FirstOrDefault()LastOrDefault()

List<double> numbers = new List<double>()
{
    1, 2, 3, 7, 8, 9
};

double input = 5;

numbers.Sort();

double nextHighest = numbers.FirstOrDefault(x => x > input);
double nextLowest = numbers.LastOrDefault(x => x < input);

Better version edit This wont actually work for both cases 更好的版本编辑这在两种情况下都无法正常工作

Originally I suggested this as a more efficient solution, but this will not work for the number before a given input. 最初,我建议将其作为更有效的解决方案,但这不适用于给定输入之前的数字。 It only works for finding a number after the given input. 它仅适用于在给定输入之后查找数字。

You can be more efficient since you are using List<T> , there is a Find() method that accepts a predicate: 由于使用的是List<T> ,因此可以提高效率,有一个Find()方法可以接受谓词:

List<double> numbers = new List<double>()
{
    1, 2, 3, 7, 8, 9
};

double input = 5;

numbers.Sort();

double nextHighest = numbers.Find(x => x > input);

This will exit the loop immediately upon finding a match (whereas LastOrDefault() has to iterate the entire collection ) 找到匹配项后,这将立即退出循环 (而LastOrDefault()必须迭代整个集合

Fiddle for both here 这里小提琴

LinQ-Solution: LinQ解决方案:

double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };

double higher=list.OrderBy(q=>q).First(q=>q>index); // 7
double lower=list.OrderByDescending(q=>q).First(q=>q<index); // 3

Explanation: First you sort the list Ascending or Descending. 说明:首先,您对列表升序或降序进行排序。 After that all you have to do is to find the greater or smaller number; 之后,您要做的就是找到更大或更小的数字;

You might want to replace First() by FirstOrDefault() if you do not want an exception if no higher/lower value exists. 如果您不希望在没有较高/较低值的情况下发生异常,则可能希望用FirstOrDefault()替换First()

One solution would be sort the list and then iterate over it to find the spot where list[i] < index < list[i+1]. 一种解决方案是对列表进行排序,然后对其进行迭代以找到list [i] <index <list [i + 1]的位置。 This would take O(n * log(n)) time. 这将花费O(n * log(n))时间。

A better solution is simply iterate over the list and use 2 variables that you will update accordingly (let's say max and min ). 更好的解决方案是简单地遍历列表并使用2个变量,您将对其进行相应的更新(例如maxmin )。

max will store the maximum value that is below the index. max将存储低于索引的最大值。

min will store the minimum value that is above the index. min将存储高于索引的最小值。

That last solution takes O(n) time. 最后一个解决方案需要O(n)时间。

In case you want all the occurency 万一你想所有发生

double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
for(int i =1 ; i <= 9-5 ; i++)
{
    List<double> NextHigh = list.Where(x=> x-i == index).ToList();
    if(! (NextHigh.Count == 0))
    {
        NextHigh.Dump();
        break;
    }
}

for(int i =1 ; i <= 5-1 ; i++)
{
    List<double> NextLow = list.Where(x=> x+i == index).ToList();
    if( !(NextLow.Count== 0))
    {
        NextLow.Dump();
        break;
    }
}

The other answer given is not very good if you are going to be using a large list of values, because it needs to index the list twice. 如果要使用较大的值列表,则给出的另一个答案不是很好,因为它需要对列表进行两次索引。

If you make your own loop like this: 如果您这样创建自己的循环:

double higher = Double::MaxValue;
double lower = Double::MinValue;

double index = 5; // the value you want to get.
List<double> list = {1,2,3,7,8,9}; // the list you're searching.

for(int i = 0; i < list.Count; i++) 
{
    if(list[i] > index && list[i] < higher)
        higher = list[i]; // sets the higher value.
    else if(list[i] < index && list[i] > lower)
        lower = list[i]; // sets the lower value.
}

After execution, this would give you 3 and 7, the correct values. 执行后,这将为您提供3和7的正确值。

I should note that this takes O(n) time, because it only loops once. 我应该注意,这需要O(n)时间,因为它只循环一次。 This will be faster than anything posted at the time of this edit (plus it's pretty easy to see what its doing). 这将比进行此编辑时发布的任何内容都要快(此外,很容易看到它在做什么)。

You can archieve that by this way. 您可以通过这种方式存档。 These codes below was tested from my side. 下面的这些代码是从我这边经过测试的。

    double index = 5;
    double higher = 0 ;
    double lower = 0;

    List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
    list.Sort();//Sort list from low to high numbers

    if(!list.Contains(index))
    {
      foreach (var item in list)
      {
         if(item < index)
         {
            lower = item;                      
         }
         if (item > index)
         {
             higher = item;  
             break;  
         }
       }
     }
Console.WriteLine(index);//5
Console.WriteLine(lower);//3
Console.WriteLine(higher);//7

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

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