根据指定的间隔将浮点值映射到函数

时间:2014-03-09 14:00:26

标签: c++ c++11

目标

给定一个主间隔,例如[0,1],在任意数量的子间隔中打破该间隔,例如[0,0.2) , [0.2,0.5) , [0.5,1]
现在将不同的函数映射到生成的每个子区间:

[0,0.2)   ~> a( float x )
[0.2,0.5) ~> b( float x )
[0.5,1]   ~> c( float x )

调用映射函数mapmap映射函数已取消分配 在主间隔上获取浮点值,并调用相应的映射函数。也就是说,给定输入值x = 0.3map调用b(0.3)

map(0.3); //Should call b(0.3) 

我的问题是:在C ++上实现此功能的正确/最佳方式是什么?

尝试解决方案:

我尝试过一种解决方案,它将表示间隔表示为一对浮点值,即using interval = std::pair<float,float>;,并使用该区间类型作为(无序)映射的键:

void map_function( float x )
{
    std::map<interval,std::function<void(float)>> map;

    map[{0.0,0.2}] = [](float){ ... }; //a
    map[{0.2,0.5}] = [](float){ ... }; //b
    map[{0.5,1.0}] = [](float){ ... }; //c

    auto it = std::find_if( std::begin( map ) , 
                            std::end( map ) ,
                            [x]( const interval& interval )
    {
        return x >= interval.first && x < interval.second;
    });

    if( it != std::end( map ) )
        *it( x );
    else
        throw "x out of bounds or subintervals ill-formed";
}

这个解决方案似乎有效,但我认为有一些小问题:

  • 给定n个子间隔,它具有O(n)复杂度。有没有办法在O(1)中执行这种功能?
  • std::map是否适合这项工作?:关联容器的目的是从键映射到值,但这里的映射键不是输入本身,是输入的处理形式(输入值所属的间隔) 我也尝试过C ++ 11的std::unordered_map,但似乎没有浮点对的标准哈希函数。这让我感到惊讶,但又陷入了另一个问题。继续主题:P

替代解决方案? Requeriments

我了解间隔库,例如Boost Interval和Boost Interval Container库,但我需要一个仅依赖于标准库设施的解决方案。

2 个答案:

答案 0 :(得分:4)

您可以使用binary search O(lg n)复杂性。具体来说,lower bound形式#algorithm图书馆。如果你有一个tuple <double, ptr_function>的向量,你可以使用它进行比特搜索。如果范围是特定的const长度或长度是某个数字的倍数,则可以在 O(1)时间内完成。例如:

multiple of 0.1
Ranges: [0;0.4) = a, [0.4;0.5) = b, [0.5;1) = c
table = {a,a,a,b,c,c,c,c,c}
Getting for x : table[floor(x*10)]

编辑:如果您想保留地图,可以使用地图lower bound

答案 1 :(得分:3)

如果您的时间间隔彼此相邻,则只使用起点作为键,而不是使用find()使用lower_bound()。在一般情况下,你不能比log2(N)更快。如果您知道最大小数精度是多少,我建议您使用int64_t作为键。转换为int64_t ikey = 10eX * dkey,其中X是最大精度。