Усреднение значений массива структур

jkrnd

Всем здравствуйте.Есть созданный для демонстрации вопроса массив из 14 структур: первый параметр целочисленный (время в секундах от ноля часов) далее 8 вещественных параметров (измеренные значения физических величин). Необходимо усреднить этот массив по 5-ти идущим подряд структурам. То есть в результате должно из 14 -ти получиться 3 структуры (5 + 5 + 4). Вот код. Он работает.
Кликните здесь для просмотра всего текста
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#pragma warn-pck    // Отключаем предупреждение при выравнивании структуры
#pragma pack(push, 2)
struct ArchRecordStruct
{
    UINT t;
    float v[8];
};
#pragma pack(pop, 2)
UINT cntARec = 14;
struct ArchRecordStruct *arch = new struct ArchRecordStruct[cntARec];
 
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    // Инициализауия массива структур некоторыми значениями
    for (int i = 0; i < 14; i++)
    {
        arch[i].t = 10*i;
        arch[i].v[0] = 10 + i;
        arch[i].v[1] = 20 + i;
        arch[i].v[2] = 30 + i;
        arch[i].v[3] = 40 + i;
        arch[i].v[4] = 50 + i;
        arch[i].v[5] = 60 + i;
        arch[i].v[6] = 70 + i;
        arch[i].v[7] = 80 + i;
    }
    // Задача: вычислить среднее из 5-ти идущих подряд структур (по каждому из начений t и v[...])
    // Записать вычисленное в три первых элемента этого же массива
    int n = 5;              // По скольким значениям усредняем. (Значение n == 0 недопустимо!)
    int sum_t = 0;          // Накопитель суммы значений параметра t
    float sum_v[8] = {0};   // Накопители сумм значений параметров v[8]
    int k = 0;              // Индекс результирующего массива структур
    int a = 0;              // Cчётчик итераций цикла for
    for (UINT i = 0; i < cntARec; i++)
    {
        if (a == n)
        {
            arch[k].t = sum_t / a;
            arch[k].v[0] = sum_v[0] / a;
            arch[k].v[1] = sum_v[1] / a;
            arch[k].v[2] = sum_v[2] / a;
            arch[k].v[3] = sum_v[3] / a;
            arch[k].v[4] = sum_v[4] / a;
            arch[k].v[5] = sum_v[5] / a;
            arch[k].v[6] = sum_v[6] / a;
            arch[k].v[7] = sum_v[7] / a;
            sum_t = 0;
            sum_v[0] = 0;
            sum_v[1] = 0;
            sum_v[2] = 0;
            sum_v[3] = 0;
            sum_v[4] = 0;
            sum_v[5] = 0;
            sum_v[6] = 0;
            sum_v[7] = 0;
            k++;
            a = 0;
        }
        a++;
        sum_t += arch[i].t;
        sum_v[0] += arch[i].v[0];
        sum_v[1] += arch[i].v[1];
        sum_v[2] += arch[i].v[2];
        sum_v[3] += arch[i].v[3];
        sum_v[4] += arch[i].v[4];
        sum_v[5] += arch[i].v[5];
        sum_v[6] += arch[i].v[6];
        sum_v[7] += arch[i].v[7];
    }
    if (a != 0)     // Остался неусреднённый "хвостик"
    {
        arch[k].t = sum_t / a;
        arch[k].v[0] = sum_v[0] / a;
        arch[k].v[1] = sum_v[1] / a;
        arch[k].v[2] = sum_v[2] / a;
        arch[k].v[3] = sum_v[3] / a;
        arch[k].v[4] = sum_v[4] / a;
        arch[k].v[5] = sum_v[5] / a;
        arch[k].v[6] = sum_v[6] / a;
        arch[k].v[7] = sum_v[7] / a;
    }
    // В переменной k последний индекс нового усреднённого массива (= 2)
    // Для проверки
    Label1->Caption = IntToStr(arch[0].t);              // Результат    20
    Label2->Caption = IntToStr(arch[1].t);              // Результат    70
    Label3->Caption = IntToStr(arch[2].t);              // Результат    115
 
    Label4->Caption = FormatFloat("0.0", arch[0].v[0]); // Результат    12
    Label5->Caption = FormatFloat("0.0", arch[1].v[0]); // Результат    17
    Label6->Caption = FormatFloat("0.0", arch[2].v[0]); // Результат    21.5
 
    Label7->Caption = FormatFloat("0.0", arch[0].v[7]); // Результат    82
    Label8->Caption = FormatFloat("0.0", arch[1].v[7]); // Результат    87
    Label9->Caption = FormatFloat("0.0", arch[2].v[7]); // Результат    91.5
}
В реале количество структур не 14, а несколько тысяч. И усреднять нужно когда по 5-ти, когда и по 20-ти индексам. Может кто подскажет, как упростить (ускорить работу) столь громоздкой конструкции?
3 ответа

jkrnd

Лучше пусть остается как есть сейчас. Быстрее не будет.Я, конечно, могу предложить тебе вариант с переопределением операций "+=" и "/" для ArchRecordStruct, что позволит записать весь вышеприведенный код в три строки, но это не сделает его более быстрым.


jkrnd

volvo, volvo, хотелось бы укоротить код без потери понятности и скорости. Можно
            arch[k].v[0] = sum_v[0] / a;
            arch[k].v[1] = sum_v[1] / a;
            arch[k].v[2] = sum_v[2] / a;
            arch[k].v[3] = sum_v[3] / a;
            arch[k].v[4] = sum_v[4] / a;
            arch[k].v[5] = sum_v[5] / a;
            arch[k].v[6] = sum_v[6] / a;
            arch[k].v[7] = sum_v[7] / a;
заменить циклом for? А обнуление всех членов массива
            sum_v[0] = 0;
            sum_v[1] = 0;
            sum_v[2] = 0;
            sum_v[3] = 0;
            sum_v[4] = 0;
            sum_v[5] = 0;
            sum_v[6] = 0;
            sum_v[7] = 0;
записать (не знаю как) одной строкой?скорость не уменьшится?обнулить массив кажется можно так:
memset(sum_v, 0, 8*sizeof(float));


jkrnd

В обоих случаях можно применить цикл.