Himis erster Vorschlag, der ja doch irgendwie am "Gerechtesten" klingt, lässt sich so vereinheitlichen:
"percent" seien die ungerundeten, "rounded" die gerundeten Prozentzahlen.
"dir" = CompareValue(100, Sum(rounded)) gibt an, ob aufgefüllt (1) oder abgezogen (-1) werden muss.
- Erstelle aus percents eine neue Liste, indem jedem x "dir * (0.5 - Frac(x))" zugeordnet wird
- Schmeiße aus ihr alle Einträge < 0 raus (=> falsche Rundungsrichtung)
- Sortiere sie aufsteigend
- Nimm davon die ersten "Abs(100 - Sum(rounded))" - das sind die Zahlen, deren gerundete Werte um dir erhöht werden müssen.
Getippt und getestet
.
Das einzige Problem ist, dass Delphi für solche mathematischen Spielereien nicht sehr geeignet ist; wer bei meiner Beschreibung an funktionale Funktionen (
) wie
map und
filter denkt, denkt genau richtig. Die gibt es in Delphi von Haus aus zwar nicht, aber wenigstens könnte man sie nun - im Gegensatz zu so komischen Sprachen wie Java - mithilfe von Generics, Class Helpers und anonymen Methoden nachbilden. Da dürfte es aber trotzdem schneller sein, meine Beschreibung in ein paar imperative Schleifchen zu übersetzen
.
/Edith: Ihr seid einfach zu schnell
.
Zitat von
Matze:
Danke, aber ich habe wohl vergessen zu erwähnen, dass das performant sein muss. *g*
Wenn man davon ausgeht, dass die Anzahl der auszubessernden Zahlen proportional zur Arraygröße steigt, ist Himis Algo O(n²), meiner O(n log n) (nur das Sortieren fällt ins Gewicht).