2016-08-08 47 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单位名称相同的功能。

如果您希望使用内置在库代码中,你可以使用SumIntMath单位:

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

SumInt执行使用Integer累加器的总和。这可能比使用浮点累加器的定制函数更快。但是,一个Integer累加器可能会发生溢出,这可能是不合格的。另一方面,一个Integer累加器可能比浮点累加器更准确。根据您的使用要求,这些问题可能对您很重要。

在麻烦的情况下,如果输入数组的长度为零,则会引发运行时浮点除以零错误。

+0

我只是看了看柏林的'SumInt',它和你做的基本一样,虽然它跳过了循环(循环展开等)以使事情变得更快一些。它会打开溢出检查,即使它们已关闭(并在之后恢复之前的状态)。所以作者也必须考虑这一点。 FWIW,不是最快的,但是复制并排序数组可能会避免可能发生的溢出。它也可以很早就检测到溢出。毕竟,Mean的结果不会溢出,所以应该可以做到这一点而不会溢出。 –

4

如果数组有添加或删除,重新从头开始重新计算平均值可能会相当耗时。

在这种情况下,可能需要计算运行平均值。

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

如果您有一个方便的运行总和,您可以避免舍入误差和计算一个确切的平均值。

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; 

如果性能问题,在单个循环中计算所有需要的值会更有意义。

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

运行总和会做,国际海事组织。 –

+0

是的,但只有当你有这个运行总和方便开始。 – Johan

相关问题