2016-08-08 12 views
1

私はダイナミックアレイを作成し、それに値を渡しました。動的配列の平均を見つけるためのショートカットはありますか?ダイナミックアレイの平均を見つける最も簡単な方法

var 
    TheMin, TheMax: Integer; 
    x: array of Integer; //Dynamic array declaration 
.... 
TheMin := MinIntValue(x);//I am able to retrieve the minium value of the dynamic array 
TheMax := MaxIntValue(x);//I am able to retrieve the maximum value of the dynamic array 

数学ライブラリを使用する別の方法がありますか?

答えて

6

このような関数を書くのは非常に簡単です。

function Mean(const Data: array of Integer): Double; overload; 
var 
    i: Integer; 
begin 
    Result := 0.0; 
    for i := low(Data) to high(Data) do 
    Result := Result + Data[i]; 
    Result := Result/Length(Data); 
end; 

それはMath単位で同じ名前の関数と一緒に座ることができるように私はこれを、オーバーロード。

あなたがMathユニットからSumIntを使用することができますライブラリのコードに組み込まれて使用したい場合は

TheMean := SumInt(x)/Length(x); 

SumIntIntegerアキュムレータを使用して集計を行います。おそらく、浮動小数点アキュムレータを使用する別注機能よりも高速です。しかしながら、アキュムレータIntegerは潜在的にオーバーフローの影響を受けやすく、オフフッティングする可能性があります。一方、アキュムレータIntegerは、潜在的に浮動小数点アキュムレータよりも正確です。使用要件によっては、これらの問題が重要な場合があります。

場合によっては、入力配列の長さがゼロの場合、ランタイム浮動小数点除算ゼロエラーが発生します。

+0

は、私はちょうどベルリンの 'SumInt'で見ていたし、それが少し速く、物事を作るために(などのループ展開、)フープを介してジャンプがそれは、基本的にあなたがそうであるように同じことを行います。オフになっていてもオーバーフローチェックをオンにします(その後の前の状態に戻します)。だから著者はこれも考慮しなければならなかった。 FWIW、最速ではありませんが、コピーを作成して配列をソートすると、それ以外の場合に起こりうるオーバーフローを回避できます。また、非常に早くオーバーフローを検出することもできます。結局のところ、Meanの結果はオーバーフローすることができないので、オーバーフローせずにこれを行うことが可能でなければなりません。 –

4

アレイに追加または削除がある場合は、平均値を最初から再計算するとかなり時間がかかることがあります。

その場合、代わりに実行中の平均を計算する価値があります。

合計の計算が便利な場合は、丸め誤差を回避し、正確な平均を計算できます。

function RecalcAverage(var RunningTotal: Int64; const OldArray, Additions, Deletions: TIntArray): double; overload; 
var 
    i: integer; 
begin 
    for i:= 0 to Length(Deletions) -1 do begin 
    RunningTotal:= RunningTotal - Deletions[i]; 
    end; 
    for i:= 0 to Length(Additions) -1 do begin 
    RunningTotal:= RunningTotal + Additions[i]; 
    end; 
    Result:= RunningTotal/(Length(OldArray) + Length(Additions) - Length(Deletions)); 
end; 

パフォーマンスが問題であれば、必要な値をすべて1ループで計算するほうがはるかに意味があります。

type 
    TStats = record 
    MaxVal: integer; 
    MinVal: integer; 
    Average: double; 
    end; 

function CalcStats(const input: TIntArray): TStats; 
var 
    MinVal, MaxVal: integer; 
    Total: Int64; 
    i: integer; 
begin 
    Assert(Length(input) > 0); 
    MinVal:= input[0]; 
    MaxVal:= MinVal; 
    Total:= MinVal; 
    for i:= 1 to Length(input) -1 do begin 
    MinVal:= Min(MinVal, input[i]); 
    MaxVal:= Max(MinVal, input[i]); 
    Total:= Total + input[i]; 
    end; 
    Result.MinVal:= MinVal; 
    Result.MaxVal:= MaxVal; 
    Result.Average:= Total/Length(input); 
end; 
+0

実行合計は、IMOになります。 –

+0

はい、しかし、あなたがその手始めとして便利な和を持っている場合に限ります。 – Johan

関連する問題