Forum: PC-Programmierung Eine einfache binäre Suche


von Miffel (Gast)


Lesenswert?

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?

von Sam .. (sam1994)


Lesenswert?

dafür nimmt man ein Directory<int,int>
Willst du es allerdings durchzählen sollte man vielleicht eher eine 
SortedLinkedList nehmen.

von Karl H. (kbuchegg)


Lesenswert?

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

von Miffel (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.