gpt4 book ai didi

c# - 平均列表的最有效方法

转载 作者:太空宇宙 更新时间:2023-11-03 21:28:28 24 4
gpt4 key购买 nike

我正在为图形应用程序保留一个滚动累加器,其中一个功能是提供样本的运行平均值。

累加器的大小是可变的,但本质上最终目标是这样实现的。

累加器类(丑陋但实用)

    public class accumulator<t>
{

private int trim;

List<t> _points = new List<t>();
List<string> _labels = new List<string>();
List<t> _runAvg = new List<t>();
List<t> _high = new List<t>();
List<t> _low = new List<t>();

public List<t> points { get { return _points; } }
public List<string> labels { get { return _labels; } }
public List<t> runAvg { get { return _runAvg; } }
public List<t> high { get { return _high; } }
public List<t> low { get { return _low; } }

public delegate void onChangeHandler(accumulator<t> sender, EventArgs e);
public event onChangeHandler onChange;

public accumulator(int trim)
{
this.trim = trim;
}

public void add(t point, string label)
{
if (_points.Count == trim)
{
_points.RemoveAt(0);
_labels.RemoveAt(0);
_runAvg.RemoveAt(0);
_high.RemoveAt(0);
_low.RemoveAt(0);
}

_points.Add(point);
_labels.Add(label);

if (typeof(t) == typeof(System.Int32))
{
int avg = 0;
if (_high.Count == 0)
{
_high.Add(point);
}
else
{
t v = (Convert.ToInt32(point) > Convert.ToInt32(_high[0])) ? point : _high[0];
_high.Clear();
for (int i = 0; i < _points.Count; i++) _high.Add(v);
}

if (_low.Count == 0)
{
_low.Add(point);
}
else
{
t v = (Convert.ToInt32(point) < Convert.ToInt32(_low[0])) ? point : _low[0];
_low.Clear();
for (int i = 0; i < _points.Count; i++) _low.Add(v);
}

foreach (t item in _points) avg += Convert.ToInt32(item);
avg = (avg / _points.Count);
_runAvg.Add((t)(object)avg);
//_runAvg.Add((t)(object)_points.Average(a => Convert.ToInt32(a)));
}

if (typeof(t) == typeof(System.Double))
{
double avg = 0;
if (_high.Count == 0)
{
_high.Add(point);
}
else
{
t v = (Convert.ToDouble(point) > Convert.ToDouble(_high[0])) ? point : _high[0];
_high.Clear();
for (int i = 0; i < _points.Count; i++) _high.Add(v);
}

if (_low.Count == 0)
{
_low.Add(point);
}
else
{
t v = (Convert.ToDouble(point) < Convert.ToDouble(_low[0])) ? point : _low[0];
_low.Clear();
for (int i = 0; i < _points.Count; i++) _low.Add(v);
}

foreach (t item in _points) avg += Convert.ToDouble(item);
avg = (avg / _points.Count);
_runAvg.Add((t)(object)avg);
//_runAvg.Add((t)(object)_points.Average(a => Convert.ToDouble(a)));
}
onChangeHappen();
}

private void onChangeHappen()
{
if (onChange != null) onChange(this, EventArgs.Empty);
}
}

正如您基本上看到的那样,我想保留一个运行平均值,一个高/低标记(具有相同的数据点数,因此它直接绑定(bind)到扩展系列类中的图表控件)

平均值是我认为是什么让我很沮丧,必须将列表的每个元素加到总和/除以计数当然是实现平均值的方式,但是循环是最有效的方法吗?

我试了一下 lambda 表达式(已注释掉),但我想在某种程度上它必须做同样的事情。 (有点像使用通用列表 VS 数组,我认为它必须在某处重新声明一个数组并四处移动元素,但它可能比我做的更有效或更有效,所以为了方便起见让它这样做)

最终目标和最终问题是真实的,给定通用值列表...

平均整个列表的最有效方法。

*注意:我确实意识到键入 int/floats 的迂腐本质,这是因为在我无法控制的此类的使用者中进行类型检查,它实际上看起来是如果它是 double/int 否则我会把它全部当作 float ;)

提前致谢...

最佳答案

保持运行平均值实际上非常容易。您不需要每次都对整个列表求和,因为您已经有了它!

一旦您获得当前平均值(来自您的循环),您只需执行以下操作:

((oldAverage * oldCount) + newValue) / newCount

这将为您提供包含新值的旧集合的平均值。

要获得初始平均值,请考虑使用 LINQ 中的 Average 函数:

double average = listOfInts.Average();

关于c# - 平均列表<int>的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25537895/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com