繁体   English   中英

当匹配计数大于某个阈值时,我可以使用 C++20 范围来中断吗?

[英]Can I use C++20 ranges to break when matched count is greater than some threshold?

考虑以下前置范围代码:

std::vector<int> v(1000*1000);
bool count_gt_5_v1(int val){
    return std::count(v.begin(), v.end(), val)>5;
}

它看起来比原始循环更好,但如果 val 在 v 中很常见,它可能会非常低效。

有什么方法可以使用 C++20 范围,以便在我遇到 val 6 次后停止迭代。 换句话说,我正在寻找一种在满足我的条件时引入休息的方法。 我有这个可憎的东西,这似乎有效,但它比原始 for 循环丑得多。

bool count_gt_5_v2(int val){
    int cnt=0;
    auto span = std::ranges::views::take_while(v,[&cnt, &val]
    (const auto elem)
    {
        cnt+=elem==val; 
        return cnt<6;
    });
    std::ranges::distance(span);
    return cnt==6;
}

完整代码链接: https://godbolt.org/z/86djdK

你可以这样做:

auto matches = v | rv::filter([=](int i){ return i == val; })
                 | rv::take(6);
return ranges::distance(matches) == 6;

或更好:

auto matches = v | rv::filter([=](int i){ return i == val; });
return not ranges::empty(matches | rv::drop(5));

这次尝试:

std::ranges::views::take_while(v, [&cnt, &val](const auto elem){
    cnt+=elem==val; 
    return cnt<6;
});

不符合take_while的要求。 范围内的所有谓词都必须保持相等- 相同的输入,相同的 output。 在这里,情况并非如此——如果我们在一个元素上调用谓词两次,我们会得到不同的 output。 所以这是未定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM