查找动态数组平均值的最简单方法

时间:2016-08-08 11:05:08

标签: delphi dynamic-arrays

我创建了一个动态数组,并将值传递给它。是否有找到动态数组平均值的快捷方式。

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 

还有其他方法可以使用数学库。

2 个答案:

答案 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;