Вот как я это сделаю. Для простоты я пересмотрел данные следующим образом:
struct Data
{
int timeOfArrival;
int value;
};
Один из способов сделать то, что вы просили, чтобы использовать кольцевой буфер, где вы храните только объем данных, которые вам нужны для скользящего среднего.
enum { MOVING_AVG_SIZE = 64, }; // number of elements that you use for your moving average
std::vector<Data> buffer(MOVING_AVG_SIZE);
std::vector<Data>::iterator insertIt = buffer.begin();
// saving to circular buffer
Data newData;
++insertIt
if (insertIt == buffer.end()) insertIt = buffer.begin();
*insertIt = newData;
// average
int sum = 0;
for (std::vector<Data>::const_iterator it = buffer.begin(); it != buffer.end(); ++it)
{
sum += it->value;
}
float avg = sum/(float)buffer.size();
Если вы не циклический буфер, и вы просто продолжать добавлять значения вашего вектора, то вы можете просто получить последнее число элементов, необходимых для расчета вашего скользящего среднего.
// saving to circular buffer
Data newData;
buffer.push_back(newData);
// average
// this algorithm calculates the moving average even if there is not enough samples in the buffer for the "10 s"
std::vector<Data>::const_reverse_iterator it = buffer.rbegin();
int i;
int sum = 0;
for (i = 0; i < MOVING_AVG_SIZE || it == buffer.rend(); ++i)
{
sum += it->value;
}
float avg = sum/(float)i;
Будете ли вы хранить больше, чем те 10 с данных в векторе? Если нет, вы можете рассматривать это как круговой буфер. Затем вы можете просто вычислить сумму всего вектора. Когда вы добавляете новые элементы, вам нужно начинать добавлять в начале, как только вы достигнете конца. Если у вас нет кругового буфера, вы просто получаете итератор к последнему элементу и вычисляете сумму элементов из него до 10 сек. Назад (в зависимости от количества элементов). – rozina