Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#11

Re: Wie aus Daten ganze prozentuale Ergebnisse berechnen

  Alt 15. Feb 2009, 12:24
Und das obwohl's noch nichtmal fertig war/ist

Och, sooooo inperformant isses nun auch nicht.
Meistens wird der meiste ja eh nicht ausgeführt und nach maxinam nur einer Runde wird's oftmals auch schon fertig sein.

Die Funktion Math.SumInt hab ich jetzt absichtlich nicht verwendet, da die erste Sum-Schleife schon für die Parameter-Kontrolle verwendet wurde und due 2 kleine Schleife die Bereichsprüfungen der Math.SumInt nicht benötigt.

Es können auch nur negative oder nur positive Werte übergeben werden.

Na gut, ich denk ein paar Optimierungen wären noch möglich, aber erstmal gucken, ob es auch richtig funktioniert.

Delphi-Quellcode:
Uses Types;

Function RoundedPercentage(Const Values: Array of Integer): TIntegerDynArray;
  Var i, i2: Integer;
    Maximum: Int64;
    ResultR: Array of Real;
    MinMaxR: Real;

  Begin
    Maximum := 0;
    For i := 0 to High(Values) do Begin
      If ((Maximum < 0) and (Values[i] > 0))
          or ((Maximum > 0) and (Values[i] < 0)) Then
        Raise Exception.CreateFmt('Invalid Value (%d)', [Values[i]]);
      Inc(Maximum, Values[i]);
    End;
    SetLength(Result, Length(Values));
    SetLength(ResultR, Length(Values));
    For i := 0 to High(Values) do Begin
      ResultR[i] := Values[i] / Maximum * 100;
      Result[i] := Round(ResultR[i]);
    End;
    While True do Begin
      i2 := 0;
      For i := 0 to High(Values) do Inc(i2, Result[i]);
      If i2 < 100 Then Begin
        MinMaxR := -1;
        i2 := -1;
        For i := High(Values) downto 0 do
          If Round(Int(ResultR[i])) = Result[i] Then
            If Abs(Frac(ResultR[i])) > MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
        If i2 < 0 Then Begin
          MinMaxR := -1;
          i2 := -1;
          For i := High(Values) downto 0 do
            If Abs(Frac(ResultR[i])) > MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
          If i2 < 0 Then i2 := High(Values);
          Inc(Result[i2]);
        End Else Inc(Result[i2]);
      End Else If i2 > 100 Then Begin
        MinMaxR := -1;
        i2 := -1;
        For i := High(Values) downto 0 do
          If Round(Int(ResultR[i])) <> Result[i] Then
            If Abs(Frac(ResultR[i])) < MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
        If i2 < 0 Then Begin
          MinMaxR := -1;
          i2 := -1;
          For i := High(Values) downto 0 do
            If Abs(Frac(ResultR[i])) < MinMaxR Then Begin
              MinMaxR := Abs(Frac(ResultR[i]));
              i2 := i;
            End;
          If i2 < 0 Then i2 := High(Values);
          Inc(Result[i2]);
        End Else Inc(Result[i2]);
      End Else Break;
    End;
  End;

Procedure TForm1.FormCreate(Sender: TObject);
  Var R: TIntegerDynArray;
    i: Integer;

  Begin
    R := RoundedPercentage([1545, 1545, 1545, 1545, 1545, 1545, 730]);
    Caption := '';
    For i := 0 to High(R) do
      Caption := Caption + ' ' + IntToStr(R[i]);
  End;
[add]
@Khabarakh: hop hop, Beeilung .. zwei Funktionen sind besser als eine
$2B or not $2B
  Mit Zitat antworten Zitat