Ich habe eine Liste mit Zahlen, und wenn die gesuchte Nummer nicht in der Liste enthalten ist, möchte ich den nächsten Wert in der Liste über und unter der von mir angeforderten Nummer finden können.

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;

Da beispielsweise 5 nicht genau in der Liste selbst enthalten ist, möchte ich, dass das nächste Element zurückgegeben wird, das sowohl oben als auch unten am nächsten an 5 liegt. also für diesen Fall 3 und 7.

c#
1
Stavros 18 Apr. 2018 im 17:18

5 Antworten

Eine Lösung wäre, die Liste zu sortieren und dann darüber zu iterieren, um die Stelle zu finden, an der Liste [i] O(n * log(n)) Zeit in Anspruch nehmen.

Eine bessere Lösung besteht darin, einfach die Liste zu durchlaufen und 2 Variablen zu verwenden, die Sie entsprechend aktualisieren (sagen wir max und min).

max speichert den Maximalwert, der unter dem Index liegt.

min speichert den Mindestwert, der über dem Index liegt.

Diese letzte Lösung benötigt O(n) Zeit.

0
Cosmin Ioniță 18 Apr. 2018 im 14:27

LinQ-Lösung:

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

Erläuterung: Zuerst sortieren Sie die Liste aufsteigend oder absteigend. Danach müssen Sie nur noch die größere oder kleinere Zahl finden.

Möglicherweise möchten Sie First() durch FirstOrDefault() ersetzen, wenn Sie keine Ausnahme wünschen, wenn kein höherer / niedrigerer Wert vorhanden ist.

0
Ole Albers 18 Apr. 2018 im 14:28

Für den Fall, dass Sie alle Vorkommen wollen

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;
    }
}
0
Daniele Sartori 18 Apr. 2018 im 14:39

Die andere Antwort ist nicht sehr gut, wenn Sie eine große Liste von Werten verwenden möchten, da die Liste zweimal indiziert werden muss.

Wenn Sie Ihre eigene Schleife wie folgt erstellen:

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

Nach der Ausführung erhalten Sie 3 und 7 die richtigen Werte.

Ich sollte beachten, dass dies O (n) Zeit benötigt, da es nur einmal Schleifen gibt. Dies ist schneller als alles, was zum Zeitpunkt dieser Bearbeitung veröffentlicht wurde (und es ist ziemlich einfach zu sehen, was es tut).

0
Sudsy1002 18 Apr. 2018 im 15:49

Sie können dies auf diese Weise erreichen. Diese Codes unten wurden von meiner Seite getestet.

    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
-1
Nguyen Thanh Binh 18 Apr. 2018 im 14:54