BAGZZlash
Lt. Junior Grade
- Registriert
- März 2008
- Beiträge
- 382
Ich habe ein einsbasiertes Array mit Werten. Diese Werte sind in dem Sinne geordnet, dass sie zunächst ansteigen, ab einem bestimmten Punkt aber wieder absteigen. Wo das Maximum liegt und wie viele Werte enthalten sind, kann unterschiedlich sein. Der erste Wert ist immer null.
Beispiel:
Ich möchte nun den Index des Maximums ermitteln, aber, ganz wichtig, dabei so wenige Indizes wie möglich "besuchen" müssen. Einfach am Anfang loslaufen und aufhören, wenn die Werte wieder kleiner werden, ist keine Option.
Meine Idee ist durch die Binärsuche inspiriert, aber mit Stack. Der Stack wird mit 1 vorinitialisiert. "CurrentMax" wird mit 0 vorinitialisiert.
In der ersten Iteration umfasst der "Suchast" das gesamte Array, d.h. die linke Grenze ist 1 und die rechte Grenze ist 16. Die Mitte davon ist 8:
Der Wert dort ist 14, also größer als CurrentMax, daher wird CurrentMax nun 14 zugewiesen. Was soll ich an dieser Stelle nun machen? Nach rechts gehen oder nach links? Keine Ahnung, aber ich entscheide mich mal für rechts. Middle wird auf den Stack gepusht und Left soll nun gleich Middle sein:
Dort steht 23 > CurrentMax, daher CurrentMax = 23, weiter nach rechts gehen. Also push Middle und Left = Middle:
Dort steht 19 < CurrentMax, das gesuchte Maximum muss nun also sicher weiter links stehen. Es könnte an Position Nr. 13 stehen, daher nun pop Left und Right = Middle:
Hier steht 21, das Maximum ist also nicht getroffen. Das Maximum könnte die 23 bei Position 12 sein, aber es könnte auch noch links von Position 12 stehen. Aktuell sind wir bei 13. 12 und 14 wurden schon besucht, wir müssen also hier raus springen. Aber wohin? Es ist jetzt naheliegend, die 8 vom Stack zu poppen, das aktuelle Left zum neuen Right zu machen und damit fortzufahren:
Dort steht 34 > CurrentMax. Nach rechts gehen? Okay, dann:
Dort steht 29 < CurrentMax, also nicht weiter nach rechts gehen. Hm, der gesuchte Wert könnte auch noch an Position 9 stehen. Eigentlich müsste ich jetzt das neue Right durch das alte Left festlegen und für das neue Left die 8 poppen. Aber die ist ja schon nicht mehr auf dem Stack, sie wurde ja schon nach Interation 4 "verbraten".
Angenommen, ich hätte die 8 noch. dann wäre der nächste Schritt:
Damit wäre klar, dass das Maximum an der Stelle 10 liegt. 9 haben wir besucht (< 34) und 11 haben wir auch besucht (< 34), wir wären also fertig und hätten nur 7 von 15 offenen Positionen besuchen müssen.
Aber, wie Ihr seht: Ich bin noch nicht sicher, wie ich das Ganze in einen Algorithmus gießen soll. Könnt Ihr mir helfen?
Beispiel:
Code:
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
Ich möchte nun den Index des Maximums ermitteln, aber, ganz wichtig, dabei so wenige Indizes wie möglich "besuchen" müssen. Einfach am Anfang loslaufen und aufhören, wenn die Werte wieder kleiner werden, ist keine Option.
Meine Idee ist durch die Binärsuche inspiriert, aber mit Stack. Der Stack wird mit 1 vorinitialisiert. "CurrentMax" wird mit 0 vorinitialisiert.
In der ersten Iteration umfasst der "Suchast" das gesamte Array, d.h. die linke Grenze ist 1 und die rechte Grenze ist 16. Die Mitte davon ist 8:
Code:
Iteration Left Right Middle Stack
1 1 16 8 1
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Der Wert dort ist 14, also größer als CurrentMax, daher wird CurrentMax nun 14 zugewiesen. Was soll ich an dieser Stelle nun machen? Nach rechts gehen oder nach links? Keine Ahnung, aber ich entscheide mich mal für rechts. Middle wird auf den Stack gepusht und Left soll nun gleich Middle sein:
Code:
Iteration Left Right Middle Stack
2 8 16 12 1; 8
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Dort steht 23 > CurrentMax, daher CurrentMax = 23, weiter nach rechts gehen. Also push Middle und Left = Middle:
Code:
Iteration Left Right Middle Stack
3 12 16 14 1; 8; 12
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Dort steht 19 < CurrentMax, das gesuchte Maximum muss nun also sicher weiter links stehen. Es könnte an Position Nr. 13 stehen, daher nun pop Left und Right = Middle:
Code:
Iteration Left Right Middle Stack
4 12 14 13 1; 8
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Hier steht 21, das Maximum ist also nicht getroffen. Das Maximum könnte die 23 bei Position 12 sein, aber es könnte auch noch links von Position 12 stehen. Aktuell sind wir bei 13. 12 und 14 wurden schon besucht, wir müssen also hier raus springen. Aber wohin? Es ist jetzt naheliegend, die 8 vom Stack zu poppen, das aktuelle Left zum neuen Right zu machen und damit fortzufahren:
Code:
Iteration Left Right Middle Stack
5 8 12 10 1; 10
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Dort steht 34 > CurrentMax. Nach rechts gehen? Okay, dann:
Code:
Iteration Left Right Middle Stack
6 10 12 11 1
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Dort steht 29 < CurrentMax, also nicht weiter nach rechts gehen. Hm, der gesuchte Wert könnte auch noch an Position 9 stehen. Eigentlich müsste ich jetzt das neue Right durch das alte Left festlegen und für das neue Left die 8 poppen. Aber die ist ja schon nicht mehr auf dem Stack, sie wurde ja schon nach Interation 4 "verbraten".
Angenommen, ich hätte die 8 noch. dann wäre der nächste Schritt:
Code:
Iteration Left Right Middle Stack
7 8 10 9 1
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wert: 0 7 8 9 10 11 12 14 15 34 29 23 21 19 17 16
↑
Damit wäre klar, dass das Maximum an der Stelle 10 liegt. 9 haben wir besucht (< 34) und 11 haben wir auch besucht (< 34), wir wären also fertig und hätten nur 7 von 15 offenen Positionen besuchen müssen.
Aber, wie Ihr seht: Ich bin noch nicht sicher, wie ich das Ganze in einen Algorithmus gießen soll. Könnt Ihr mir helfen?