简体   繁体   中英

How to calculate the average of last 100 numbers of increasing quantity of numbers pool

I have a data source. It gives a number each minute. I want to compute the average value of the last 100 numbers. How do I do this with C?

For example, the input is 1,2,3,4, ... 150 then I want to get the average value of 50 . . . 150 50 . . . 150 50 . . . 150 .

One minute later, the number pool changes to 1,2,3,4.....150,151 , then I need to get the average value of 51. . . 151 51. . . 151 51. . . 151 , as the concept is same, get the last 100 numbers to calculate the average value.

I have tried to use a list structure, first get get total sum of all the numbers ,then subtract the sum from the first number to count-100 to get the last 100 numbers .

Here is my code i have tried:

#include <stdio.h>
#include <malloc.h>
#define N 5

int i,sum;

int main(void)
{
struct node //定义一个链表
{
    float num;  //链表的元素
    struct node *next;//下一个元素的指针
};
struct node *first=NULL;//第一个数据
struct node *current=NULL;//当前的数据
struct node *previous=NULL;//上一个数据

struct node *currentT=NULL;//
//    char temp='\0';

while (1==1)//循环输入数据,相当于每秒往链表中添加一个数据
{
    // printf("continue ?Y/N:  ");
    // scanf(" %c",&temp);

    // if (tolower(temp)=='n')
    //  break;
    current=(struct node*) malloc(sizeof(struct node));//获取链表的首地址
    if (first==NULL)//如果第一个数据为空就把当前的地址赋值给first
        first=current;
    if (previous!=NULL)//把当前的地址赋值给上一个数据的next指针
        previous->next=current;
    printf("please enter the num:");
    scanf("%f",&current->num);//输入数据
    current->next=NULL;//移动指针
    previous=current;

    currentT=first;//指针指向第一个数据
    float avg=0,sum=0,count=0;
    while (currentT!=NULL)//循环链表中所有的数据
    {
        printf("node's num is:%f \n",currentT->num);
        count=count+1;
        sum= sum+currentT->num;//求总和
        currentT=currentT->next;//指针下移

    }
    avg=sum/count;//求平均

    if(count>N)//如果链表长度大于N则减去链表前端的数据
    {
        currentT=first;//指针指向第一个数据
        int remove_count=0;
        while (currentT!=NULL)//循环链表中所有的数据
        {
            remove_count=remove_count+1;
            sum= sum-currentT->num;//求总和
            if(remove_count==count-N){//减到链表长度等于N时停止
                break;
            }
            currentT=currentT->next;//指针下移
        }
         avg=sum/N;//求平均
    }

    printf("sum is:%f \n",sum);

    printf("avg is:%f \n",avg);

}

return 0;
}

The algorithm seems simple. Keep the last 100 numbers which came in in some queue. That queue will contain 100 elements at any moment of time. Also, you keep their sum S at any time. When a new number comes in, remove the first number from the queue, and add the new number which came in to the queue. Then just recalculate the sum S of these 100 numbers by subtracting the first number and adding the new one.

S = S - aOldFirst + aNewLast;

I would use a dynamic structure (eg a linked list) for implementing the queue.

Below is a implementation of circular queue using array, and a function to return average of the elements when adding a new element. The function deletes the 1st element when queue is full. So, you can just call this function for every input and it will return the average of current elements.

//declarations
#define MAXSIZE 5
int cq[MAXSIZE]={0};
int front=-1,rear=-1;
float AverageForNewElement(int);

//function definition 
float AverageForNewElement(int item)
{
    static int Sum=0;
    if(front ==(rear+1)%MAXSIZE)
    {
        if(front==rear)
            front=rear=-1;
        else
            front = (front+1)%MAXSIZE;
        Sum=Sum-cq[front];
    }
    if(front==-1)
        front=rear=0;
    else
        rear=(rear+1)%MAXSIZE;
    cq[rear]=item;
    Sum=Sum+cq[rear];
    return ((float)Sum/MAXSIZE);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM