我创建了一个动态数组,并将值传递给它。是否有找到动态数组平均值的快捷方式。
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
还有其他方法可以使用数学库。
答案 0 :(得分: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
单元中的相同命名函数并排放置。
如果您希望使用内置库代码,可以使用SumInt
单元中的Math
:
TheMean := SumInt(x) / Length(x);
SumInt
使用Integer
累加器执行求和。这可能比使用浮点累加器的定制函数更快。但是,Integer
累加器可能会溢出,这可能是令人反感的。另一方面,Integer
累加器可能比浮点累加器更准确。根据您的使用要求,这些问题可能对您很重要。
在麻烦的情况下,如果输入数组的长度为零,则会引发运行时浮点除以零的错误。
答案 1 :(得分: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;