You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按比例筛选std::ranges::equal_range返回的大范围内均匀分布元素?

从std::ranges::equal_range结果中均匀采样元素的实现方法

要从std::ranges::equal_range返回的大范围内均匀选取指定数量的元素,无需修改原范围,直接通过视图组合就能实现需求,核心思路是利用元素索引进行筛选:

方法1:线性步长采样

先计算采样步长,再通过std::views::enumerate获取元素索引,筛选出符合步长间隔的元素:

修改后的完整代码

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>

float gen()
{
    static float v=0.0f;
    v+=0.1f;
    return v;
}

int main()
{
    const size_t some_huge_size=100;
    std::vector<float> values(some_huge_size);

    std::ranges::generate(values, gen);

    const int some_value_to_search = some_huge_size/10-1;
    auto range = std::ranges::equal_range(values,some_value_to_search,{},[](auto& v){ return int(v); });

    const int in_range_i_need_only = 4;
    const auto range_size = std::ranges::distance(range);
    
    // 计算采样步长,避免除以0
    const size_t step = (range_size <= in_range_i_need_only) ? 1 : range_size / in_range_i_need_only;

    // 生成采样视图:筛选索引为0, step, 2*step...的元素
    auto sampled_range = range 
                       | std::views::enumerate
                       | std::views::filter([step](auto&& pair) { return pair.first % step == 0; })
                       | std::views::values;

    std::ranges::for_each(sampled_range, [](auto& v) { std::cout << v << ", ";});
}

说明

  • std::views::enumerate为每个元素绑定一个从0开始的索引;
  • filter保留索引是步长整数倍的元素;
  • views::values剥离索引,还原为原元素的视图,直接传给std::ranges::for_each即可。

方法2:Bresenham算法优化采样(更均匀分布)

当范围大小无法被采样数量整除时,线性步长会导致末尾元素分布不均,用Bresenham算法可以让采样点更均匀:

替换采样逻辑的代码片段

// 替换sampled_range的生成逻辑
auto sampled_range = range
                   | std::views::enumerate
                   | std::views::filter([range_size, in_range_i_need_only](auto&& pair) {
                       const auto idx = pair.first;
                       return idx * in_range_i_need_only * 2 >= range_size * (2 * idx - 1);
                   })
                   | std::views::values;

这个逻辑基于Bresenham直线算法原理,让采样点在整个范围内均匀分布,避免线性步长的偏差。

为什么slide_view/chunk_view不合适?

slide_view和chunk_view会生成连续的子范围,而我们需要的是离散的单个元素,直接用enumerate+filter的组合更贴合需求,无需额外处理子范围的元素提取。

预期输出(为便于阅读添加额外空格):
9.1, 9.3, 9.5, 9.7,

内容的提问来源于stack exchange,提问作者Damir Tenishev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:55:00