使用STL/ranges算法计算加权平均数。

14

假设我有一个成绩向量,其中的成绩是

struct Grade{
   const int grade;
   const int ECTS; // weight
};

有没有STL/range-v3算法/算法可以让我做到这一点?

我知道我可以使用std::accumulate,并使用一些复杂的类型作为累加器(记住权重总和),但如果存在更简单的替代方法,我正在寻找它。


2
目前正在开发约束数值算法:P1813。它们将使得以下操作成为可能:ranges::inner_product(grades, grades, 0, {}, {}, &Grade::grade, &Grade::ECTS); - metalfox
2个回答

17

Grade类型本身已足够奇特,可用作累加器类型。

auto [grade_sum, ects] = std::accumulate(
    grages.begin(), grades.end(), Grade {0,0}, 
    [] (Grade acc, Grade g) -> Grade {
        return { g.grade*g.ECTS + acc.grade,
                 g.ECTS         + acc.ECTS  };
});
// auto average_grade = grade_sum/ects;

如果有必要,C++17结构化绑定可以被std::tie替换。


1
可能是 auto average_grade = double(grade_sum) / ects - Jarod42
确实有这种可能。顺便感谢您修复累加器/值的顺序 ;) - Tom

7
使用 range-v3,可能会变成这样:
auto average = ranges::inner_product(grades, grades, 0, {}, {}, &Grade::grade, &Grade::ECTS)
        / double(ranges::accumulate(grades, 0, {}, &Grade::ECTS));

Demo


1
目前,编译时间是一个阻碍因素。https://godbolt.org/z/I1_kGh与https://godbolt.org/z/eVvMJz或14448ms(ranges::inner_product)与3890ms(std::accumulate)之间的比较。 - Porsche9II

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接