Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 一种通过索引过滤范围的方法,仅从过滤的索引中获取最小元素?_C++_Templates_C++11_Boost_C++14 - Fatal编程技术网

C++ 一种通过索引过滤范围的方法,仅从过滤的索引中获取最小元素?

C++ 一种通过索引过滤范围的方法,仅从过滤的索引中获取最小元素?,c++,templates,c++11,boost,c++14,C++,Templates,C++11,Boost,C++14,在对这个问题的评论中,还有一个问题-这是否可能在容器上有“索引视图”,即筛选出一些索引的子范围 此外,我还遇到了一个问题,即从过滤掉一些索引的范围中查找最小值 也就是说,是否可以用std和/或boost算法、过滤器替换如下代码,以使其更易于阅读和维护: template <typename Range, typename IndexPredicate> auto findMin(const Range& range, IndexPredicate ipred) -

在对这个问题的评论中,还有一个问题-这是否可能在容器上有“索引视图”,即筛选出一些索引的子范围

此外,我还遇到了一个问题,即从过滤掉一些索引的范围中查找最小值

也就是说,是否可以用std和/或boost算法、过滤器替换如下代码,以使其更易于阅读和维护:

template <typename Range, typename IndexPredicate>
auto findMin(const Range& range, IndexPredicate ipred) 
     -> boost::optional<typename Range::value_type>
{
    bool found = false;
    typename Range::value_type minValue{};
    for (std::size_t i = 0; i < range.size(); ++i)
    {
        if (not ipred(i))
            continue;
        if (not found)
        {
            minValue = range[i];
            found = true;
        }
        else if (minValue > range[i])
        {
            minValue = range[i];
        }
    }
    if (found)
    {
        return minValue;
    }
    else
    {
        return boost::none;
    }
}
模板
自动findMin(常量范围和范围,索引预测ipred)
->boost::可选
{
bool-found=false;
typename范围::value_type minValue{};
对于(std::size_t i=0;i范围[i])
{
最小值=范围[i];
}
}
如果(找到)
{
返回最小值;
}
其他的
{
返回boost::无;
}
}
只是这样使用:

#include <iostream>
#include <vector>

int main() {
    std::vector<float> ff = {1.2,-1.2,2.3,-2.3};
    auto onlyEvenIndex = [](auto i){ return (i&1) == 0;};

    auto minValue = findMin(ff, onlyEvenIndex);
    std::cout << *minValue << std::endl;
}
#包括
#包括
int main(){
向量ff={1.2,-1.2,2.3,-2.3};
仅自动索引=[](自动i){return(i&1)==0;};
自动最小值=findMin(ff,仅适用于索引);

Std::CUT> P>解决这个问题的方法是在C++中过滤超出自然范围的自然方式。我的意思是,我们需要过滤索引的范围,而不是值的范围。但是从哪里我们得到索引的范围?有方法获得索引的范围。所以-请看这个:

#include <boost/range/irange.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/min_element.hpp>
#include <functional>

template <typename Range, typename IndexPredicate>
auto findMin(const Range& range, IndexPredicate ipred) -> boost::optional<typename Range::value_type>
{
    using boost::adaptors::filtered;
    using boost::irange;

    auto filtered_indexes = irange(0u, range.size()) | filtered(std::function<bool(std::size_t)>{ipred});
最后的步骤是:

auto foundMin = boost::min_element(filtered_indexes, lessByValue);
if (foundMin != std::end(filtered_indexes))
    return range[*foundMin];
else 
    return boost::none;

使用最近的标准:

#包括
#包括
#包括
int main()
{
向量rng={1.2,-1.2,2.3,-2.3};
自动偶数指数=
范围::视图::物联网(0ul,rng.size())|
范围::视图::过滤器([](自动i){return!(i&1);})
;
自动最小值ind=*范围::最小值元素(
偶数指数,[&rng](自动L,自动R){
返回rng[L]
增强
indexT
以支持跨步模板参数
size\u t stride=1
:将
++t;
替换为
std::advance(t,stride);

ItB base()常量{return b+**a();}
添加到
索引迭代器
(这供以后使用)

使用index\u stride\u range=range添加
模板;
这是一个具有编译时步长的索引范围

编写在两个
索引步幅范围
s上工作的
intersect
。输出是步幅
gcd的
索引步幅范围
(左s步幅,右s步幅)
。确定它的起点是另一项工作,但只是高中数学。请注意,
索引范围
是一种
索引范围
的类型,具有
步长=1
,因此此升级也适用于
索引范围
s

升级
index\u filter
以将
index\u stride\u range
作为第一个参数。实现方式相同(除了依赖升级的
intersect

每第n个索引(偏移量)
写一次
,这是一个
索引步长范围
,从
偏移量
大小(1+(abs(偏移量))%步长)-(大小(1+(abs(偏移量)%步长)
或类似的范围(在简单的情况下,基本上是0到无穷大——额外的数学运算是找到一个最大的数字,该数字等于符合
大小的偏移量+k*步长

现在我们得到:

auto filtered = index_filter( every_nth_index<2>(), container );
auto it = (std::min)( filtered.begin(), filtered.end() );
auto filtered=index\u filter(每第n个index(),容器);
auto-it=(std::min)(filtered.begin(),filtered.end());

我们有一个迭代器。
it.base()
将迭代器返回到包含元素的
容器中,如果
it!=filtered.end();
(不是
it.base()!=container.end()
,这是不同的)。

这是C++17的建议吗?我可以在gcc4.9中使用它吗?gcc4.9在C++11模式下工作,在C++14模式下使用clang(gcc 5.1有一些阻止c++14模式的bug)。这个建议是针对c++17或TS的,可能与c++17并驾齐驱。看,我有没有好的感觉,这种迭代器方法也可以用于在从流中读取时从每秒钟查找最小值。我的意思是,它不仅可以用于作为前向迭代器的迭代器?@PiotrNycz前面的部分答案依赖于随机访问rators(因为它存储了
start
迭代器和一个索引,并且在取消引用时会执行
*(start+index)
)。但是,是的,可以编写变体来支持“跳过每2个值”或其他任何内容。我只是注意到,我在链接问题中提供的答案几乎也是这个问题的解决方案。
#include <range/v3/all.hpp>
#include <iostream>
#include <vector>

int main() 
{
    std::vector<float> rng = {1.2,-1.2,2.3,-2.3};

    auto even_indices = 
        ranges::view::iota(0ul, rng.size()) | 
        ranges::view::filter([](auto i) { return !(i & 1); })
    ;
    auto min_ind = *ranges::min_element(
        even_indices, [&rng](auto L, auto R) { 
        return rng[L] < rng[R]; 
    });
    std::cout << rng[min_ind];
}
auto filtered = index_filter( every_nth_index<2>(), container );
auto it = (std::min)( filtered.begin(), filtered.end() );