C# 获得;“运行平均值”;名单

C# 获得;“运行平均值”;名单,c#,list,C#,List,假设我有一张清单: List<int> numbers = new List<int>(); 列表编号=新列表(); 我试图得到它的“运行平均值”。(对不起,我真的不知道怎么称呼它) 例如: 此列表中的第一项是5,5的平均值是5,因此第一项平均值是5 此列表中的第二项是7,第五项和第七项的平均值是6,因此第二项的平均值是6 此列表中的第三项是10,5、7和10的平均值是7.3,因此第三项平均值是7.3 等等 这些第一平均值,第二平均值等就是我想要得到的平均值。我该怎么

假设我有一张清单:

List<int> numbers = new List<int>();
列表编号=新列表();
我试图得到它的“运行平均值”。(对不起,我真的不知道怎么称呼它)

例如:

此列表中的第一项是
5
5
的平均值是
5
,因此第一项平均值是
5

此列表中的第二项是
7
,第五项和第七项的平均值是
6
,因此第二项的平均值是
6

此列表中的第三项是
10
5、7和10
的平均值是
7.3
,因此第三项平均值是
7.3
等等


这些第一平均值,第二平均值等就是我想要得到的平均值。我该怎么做呢?我一直在网上搜索,但老实说,我不太确定我应该找什么(

您可以尝试以下方法:

var averages = Enumerable.Range(1, numbers.Count)
               .Select(x => numbers.Take(x).Average())
               .ToList();
    List<double> FullList = GetRunningAverage(
    new List<double>() { 100, 5, 5, 6, 23, 10, 56, 32, 54, 1, 3, 85, 65, 49, 22, 65, 32, 5, 2, 4, 5, 89, 110, 55, 6, 56, 57 },
    3,  // Looking back 3 items
    3); // Looking forward 3 items
这将生成一个从
1
数字的序列。Count
。然后使用
Take
每次将得到
X
元素(您可以将
X
视为索引,唯一的区别是它从
1
开始,逐个增加到
数字。Count
)从第一个元素开始,然后获取它们的
平均值
。将它们放入列表。

尝试以下操作:

 string st = Console.ReadLine();
 string[] strs = st.Split(' ');
 List<int> numbers = new List<int>();
 List<double> averages = new List<double>();
 for (int i = 0; i < strs.Length; i++)
 {
     numbers.Add(int.Parse(strs[i]));
     averages.Add(numbers.Average());
 }
string st=控制台.ReadLine();
字符串[]strs=st.Split(“”);
列表编号=新列表();
列表平均值=新列表();
对于(int i=0;i
这将从标准输入中读取数字,数字在输入中用空格分隔。

列表

    List<int> numbers = new List<int>();
    List<double> averages = new List<double>();
如果没有其他数据,比如元素数量、持续时间等,这样一个平均值列表本身通常意义不大

当移动平均值不是一对一的值时,此方法更适合。例如,应用程序存储值。然后定期(比如每分钟一次)计算并存储平均值。

您需要的是“运行平均值”,而不是我假设的所有项目的一开始的平均值

运行平均值需要一个数字来告诉我们该向前看多远,一个数字来告诉我们该向前看多远

这将为您提供运行平均值:

public List<double> GetRunningAverage(List<double> SourceList, int ItemsBefore, int ItemsAfter)
{
    List<double> TargetList = new List<double>() { };

    // Only makes sense if the list is > 1 of course
    if (SourceList.Count > 1)
    {
        for (int i = 0; i < SourceList.Count; i++)
        {
            int LookBack =
                (ItemsBefore > i ? i : ItemsBefore);
            int LookForward =
                (ItemsAfter < SourceList.Count - i
                ? ItemsAfter : SourceList.Count - i);

            TargetList.Add(SourceList.GetRange(i - LookBack, LookBack + LookForward).Average());
        }
    }
    else
    {
        TargetList.AddRange(SourceList);
    }

    return TargetList;
}
public List GetRunningAverage(List SourceList,int ItemsBefore,int ItemsAfter)
{
List TargetList=new List(){};
//当然,只有当列表>1时才有意义
如果(SourceList.Count>1)
{
for(int i=0;ii?i:ItemsBefore);
国际展望=
(ItemsAfter
然后您可以这样使用它:

var averages = Enumerable.Range(1, numbers.Count)
               .Select(x => numbers.Take(x).Average())
               .ToList();
    List<double> FullList = GetRunningAverage(
    new List<double>() { 100, 5, 5, 6, 23, 10, 56, 32, 54, 1, 3, 85, 65, 49, 22, 65, 32, 5, 2, 4, 5, 89, 110, 55, 6, 56, 57 },
    3,  // Looking back 3 items
    3); // Looking forward 3 items
List FullList=GetRunningAverage(
新列表{100,5,5,6,23,10,56,32,54,1,3,85,65,49,22,65,32,5,2,4,5,89,110,55,6,56,57},
3、//回顾3项
3) ;//期待3项

数字。平均值();
将为您提供列表中值的当前平均值。不清楚是否需要将其保存到新列表或what@Plutonix我想他想把它保存在一个新的列表中。新的
列表
for
循环就是你所需要的。这是一个非常简单的任务…你试过写代码吗?我已经编辑了你的标题。请我们看到,“,其中的共识是“不,他们不应该”。谢谢@JohnSaunders,我将记住这一点,以备将来参考。:)是的,这是一个非常巧妙的解决方案。谢谢这是一个优雅的解决方案,但有点低效,因为每次迭代都从头开始重新计算平均值。运行时将是O(n logn),而保持运行和的简单解决方案是O(n)@DaveM我也这么认为,对于这样的简单问题,不需要使用复杂的结构。@DaveM这是真的。如果速度和性能至关重要,则应优先选择其他方法。你的方法可能更适用于OP的技能水平。不太准确,看到他接受这个答案,我不这么认为。等等,你的答案不起作用!这不会得到“运行平均值”,而是将当前列表的平均值存储到平均值列表中,即这些值为7.3(根据OP)。当数字改变时,新的平均值也会改变。当列表中只有1个和2个值时,代码有义务调用它,这使塞尔曼先生的答案更好。(为什么
averages
是一个可以添加到的列表)。