找到动态数组均值的最简单方法
Easiest way to find the mean of a dynamic array
我创建了一个动态数组,并向它传递了值。是否有查找动态数组均值的快捷方式。
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
有没有其他方法可以使用 Math 库求平均值。
写这样的函数非常容易
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);
SumInt
使用 Integer
累加器执行求和。这可能比使用浮点累加器的定制函数更快。但是,Integer
累加器可能会溢出,这可能会令人反感。另一方面,Integer
累加器可能比浮点累加器更准确。根据您的使用要求,这些问题可能对您很重要。
在其他情况下,如果输入数组的长度为零,则会引发运行时浮点除以零错误。
如果数组有添加或删除,从头开始重新计算平均值会非常耗时。
在这种情况下,计算 运行 平均值可能是值得的。
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;
我创建了一个动态数组,并向它传递了值。是否有查找动态数组均值的快捷方式。
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
有没有其他方法可以使用 Math 库求平均值。
写这样的函数非常容易
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);
SumInt
使用 Integer
累加器执行求和。这可能比使用浮点累加器的定制函数更快。但是,Integer
累加器可能会溢出,这可能会令人反感。另一方面,Integer
累加器可能比浮点累加器更准确。根据您的使用要求,这些问题可能对您很重要。
在其他情况下,如果输入数组的长度为零,则会引发运行时浮点除以零错误。
如果数组有添加或删除,从头开始重新计算平均值会非常耗时。
在这种情况下,计算 运行 平均值可能是值得的。
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;