筛选由索引范围的一种方式,仅从过滤指数得到min_element? [英] A way to filter range by indices, to get min_element from filtered indices only?

查看:174
本文介绍了筛选由索引范围的一种方式,仅从过滤指数得到min_element?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在评论这个问题<一href=\"http://stackoverflow.com/questions/30781811/is-there-a-way-to-iterate-over-at-most-n-elements-using-range-based-for-loop/\">is-there-a-way-to-iterate-over-at-most-n-elements-using-range-based-for-loop还有另一个问题 - 这是可能有一个容器的索引视图,即有过滤掉一些索引子范围

此外我遇到了一个问题,从一系列发现最小值一些指标过滤掉了。

即。是有可能取代这种code如下性病和/或升压算法,过滤器 - 以使其更具可读性和可维护性:

 模板&LT; typename的范围,类型名称指数predicate&GT;
汽车findMin(const的范围和放大器,范围,指标predicate我preD)
      - &GT;推动::可选&LT; typename的范围:: value_type的&GT;
{
    布尔发现= FALSE;
    typename的范围:: VALUE_TYPE minValue(最小值){};
    对于(的std ::为size_t我= 0; I&LT; range.size(); ++ I)
    {
        如果(没有我preD(I))
            继续;
        如果(未找到)
        {
            minValue(最小值)=范围[I]
            发现= TRUE;
        }
        否则,如果(minValue(最小值)&GT;范围[i])
        {
            minValue(最小值)=范围[I]
        }
    }
    如果(找到)
    {
        返回minValue(最小值);
    }
    其他
    {
        返回的boost ::无;
    }
}

只是要使用这样的:

 的#include&LT;&iostream的GT;
#包括LT&;矢量&GT;诠释主(){
    的std ::矢量&lt;浮球GT; FF = {1.2,-1.2,2.3,-2.3};
    自动onlyEvenIndex = [](自动ⅰ){返回(I和1)== 0;};    汽车minValue(最小值)= findMin(FF,onlyEvenIndex);
    性病::法院LT&;&LT; * minValue(最小值)&LT;&LT;的std :: ENDL;
}


解决方案

使用最近标准的 范围-V3提案

 的#include&LT;范围/ V3 / all.hpp&GT;
#包括LT&;&iostream的GT;
#包括LT&;矢量&GT;诠释的main()
{
    的std ::矢量&lt;浮球GT; RNG = {1.2,-1.2,2.3,-2.3};    汽车even_indices =
        范围::观点::丝毫(0ul,rng.size())|
        范围::观点::过滤器([](自动I){返回(I和!1);})
    ;
    汽车min_ind = *范围:: min_element(
        even_indices,[&安培; RNG](自动L,自动R){
        返回RNG [1]; RNG [R]。
    });
    性病::法院LT&;&LT; RNG [min_ind]
}

活生生的例子 。注意语法大致类似Boost.Range,但完全修补,利用C ++ 14(广义lambda表达式,自动返回类型推演等)

In comments to this question is-there-a-way-to-iterate-over-at-most-n-elements-using-range-based-for-loop there was additional question - is this possible to have "index view" on a container, i.e. to have subrange with some indexes filtered out.

Additionally I encountered a problem to find minimum value from a range with some indexes filtered out.

I.e. is it possible to replace such code as below with std and/or boost algorithms, filters - to make it more readable and maintainable:

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;
    }
}

Just to be used like this:

#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;
}

解决方案

Using the recently Standard range-v3 proposal:

#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];
}

Live Example. Note that the syntax is roughly similar to Boost.Range, but fully revamped to take advantage of C++14 (generalized lambdas, auto return type deduction etc.)

这篇关于筛选由索引范围的一种方式,仅从过滤指数得到min_element?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆