如何用C++标准库或Boost库计算浮点数组的区间直方图?
如何用C++标准库或Boost库统计数组区间数值出现次数?
嘿,这个需求我刚好熟!咱们分两部分来看——标准库的手动实现方案,还有Boost库的现成工具:
一、C++标准库:手动实现区间计数
C++标准库没有直接提供“直方图统计”的函数,但可以用<algorithm>里的工具快速实现,核心思路是先排序数组,再用二分查找定位区间边界,或者直接用count_if遍历统计。
针对你的示例数组,我们可以这么写:
#include <iostream> #include <vector> #include <algorithm> int main() { float data[] = {1.1,1.1,1.1, 2.1,2.1,2.1, 3.1,3.1,3.1, 4.1,4.1,4.1, 5.1,5.1,5.1, 1.5,1.5,1.5, 3.2,3.2,3.2}; std::vector<float> vec(data, data + sizeof(data)/sizeof(float)); std::sort(vec.begin(), vec.end()); // 二分查找需要有序数组 // 定义要统计的区间:{0,1}, {1,2}, {2,3}, {3,4}, {4,5} std::vector<std::pair<float, float>> intervals = {{0,1}, {1,2}, {2,3}, {3,4}, {4,5}}; for (auto& interval : intervals) { // 找第一个 >= 区间左边界的元素 auto left = std::lower_bound(vec.begin(), vec.end(), interval.first); // 找第一个 >= 区间右边界的元素 auto right = std::lower_bound(vec.begin(), vec.end(), interval.second); int count = std::distance(left, right); std::cout << interval.first << "-" << interval.second << " -> " << count << "次\n"; } return 0; }
运行这段代码,输出结果就和你期望的完全一致:
0-1 -> 0次
1-2 -> 6次
2-3 -> 3次
3-4 -> 6次
4-5 -> 3次
如果不想排序,也可以用std::count_if直接遍历判断元素是否在区间内,不过对于大数据量来说,排序+二分查找的效率会更高。
二、Boost库:用boost::histogram直接生成直方图
如果你不想自己造轮子,Boost的histogram库专门解决这类统计问题,用法非常直观,而且支持更复杂的直方图需求(比如多维、加权统计等)。
首先确保你已经安装了Boost库,然后可以这么写代码:
#include <iostream> #include <vector> #include <boost/histogram.hpp> int main() { float data[] = {1.1,1.1,1.1, 2.1,2.1,2.1, 3.1,3.1,3.1, 4.1,4.1,4.1, 5.1,5.1,5.1, 1.5,1.5,1.5, 3.2,3.2,3.2}; std::vector<float> vec(data, data + sizeof(data)/sizeof(float)); // 创建直方图,设置区间轴:从0到5,每1个单位为一个区间 auto h = boost::histogram::make_histogram( boost::histogram::axis::regular<>(5, 0.0, 5.0, "value") ); // 填充数据 h.fill(vec); // 遍历每个区间,输出计数 auto axis = h.axis(); for (int i = 0; i < axis.size(); ++i) { auto interval = axis.bin(i); std::cout << interval.lower() << "-" << interval.upper() << " -> " << h.at(i) << "次\n"; } return 0; }
这段代码会直接输出你要的统计结果,而且后续如果要调整区间范围、增加维度,只需要修改轴的定义即可,非常灵活。
内容的提问来源于stack exchange,提问作者infoclogged
相关产品推荐
相关产品推荐

