Eine einfache binäre Suche

Gast #1958453
Hallöchen!
Ich versuche hier gerade eine einfache binäre Suche (in C#) zu 
implementieren. Leider will es nicht funktionieren...

Die Situation: ich habe eine Liste mit Messwerten (Paare aus Wert & 
Zeitstempel). Nun möchte ich zu einem gegeben Zeitpunkt den 
entsprechenden Messwert finden (ein Messwert gilt immer bis zum 
nächsten).

Hier mein Code:
1
double GetValueAtTime( double t )
2
{
3
  // Start binary search at the middle
4
  int searchPos = mSamples.Count / 2;
5
  int searchStep = mSamples.Count / 4;
6

7
  while (searchStep > 0)
8
  {
9
    // Jump to the right
10
    if (t > mSamples[searchPos + 1].Timestamp)
11
      searchPos += searchStep;
12
      
13
    // Jump to the left
14
    else if (t < mSamples[searchPos].Timestamp)
15
      searchPos -= searchStep;
16
      
17
    // We have found the value
18
    else
19
      break;
20

21
    searchStep /= 2;
22
  }//end while
23

24
  return mSamples[searchPos].Value;
25
}

Leider bekomme ich ich ständig falsche Werte. Ich vermute mal dass das 
daran liegt, dass die Anzahl der Messwerte nicht immer eine 2er Potenz 
ist?
Oder mache ich generell etwas falsch?
#1958470
Miffel schrieb:

> Ich versuche hier gerade eine einfache binäre Suche (in C#) zu
> implementieren. Leider will es nicht funktionieren...

Sowas gibt es zwar sicherlich schon auch fertig, aber es ist löblich das 
du Basisalgorithmen lernen willst.


> Leider bekomme ich ich ständig falsche Werte. Ich vermute mal dass das
> daran liegt, dass die Anzahl der Messwerte nicht immer eine 2er Potenz
> ist?
> Oder mache ich generell etwas falsch?

Binäre Suche sieht so einfach aus, ist es aber nicht. Das Problem 
besteht darin, dass bei einer ungeraden Anzahl Elemente im Suchraum, man 
höllisch aufpassen muss, wo die Hälfte liegt und dass man dann das 
Intervall richtig neu aufteilt.


Du musst lernen dir selbst zu helfen und zu debuggen.
Und ein Weg und bei weitem nicht der schlechteste, ist es, sich an 
strategischen Stellen strategisch wichtige Variablen ausgeben zu lassen. 
In C# steht dir ohnehin ein ausgezeichneter Weg über das Developer 
Studio und dessen Output-Fenster zur Verfügung, in das man leicht Werte 
ausgeben kann.

http://support.microsoft.com/kb/815788

Also lass dir hier jeweils beim Durchgang durch den Anfang der 
Suchschleife die Variablen ausgeben
1
  while (searchStep > 0)
2
  {
3

4
>>>>   hier ist interessant: welche Werte haben searchPos und searchStep

Und dann wird dieser Mitschrieb studiert und daraus Schlüsse gezogen

> Oder mache ich generell etwas falsch?
IMHO ja.
Beim Binären suchen hat man ein Intervall, das man durch Startindex und 
Endindex definiert und nicht durch Startindex und Größe. Wird nämlich 
ein Intervall in 2 aufgeteilt und entschieden in welchem davon 
weitergesucht werden muss, dann hat dieses neue Intervall nicht 
unbedingt eine neue Größe von step / 2
Gast #1958575
@Samuel:
Die Dictionary Klasse kannte ich noch gar nicht. Kann man die denn auch 
in meinem Fall benutzen? Denn die Werte, nach denen ich suche stehen ja 
nicht explizit im Speicher.
Wenn ich z.B. zwei Werte habe:

Wert 1:  4
Zeitstempel 1: 0

Wert 2: 9
Zeitstempel: 10

Dann soll meine Suche für ALLE Zeiten 0 < t < 10 den Wert 4, für alle 
Zeiten t >= 10 den Wert 9 zurückgeben...


@KHB:
Danke für die ausführliche Antwort! Da werde ich mich wohl nochmal etwas 
hinein-vertiefen müssen...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.