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

Mapping float value to function depending on specified intervals

本文关键字:映射 函数      更新时间:2023-10-16

目标

给定一个主区间,例如[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 )

调用该映射函数map。设计了map映射函数获取主间隔上的浮点值,并调用相应的映射函数。也就是说,给定输入值x = 0.3, map调用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) 。有没有办法在0(1)中实现这种函数?
  • std::map是适合这项工作的容器吗?:关联容器的目的是从键映射到值,但这里映射的键不是输入本身,而是输入的处理形式(输入值所属的区间)。
    我也尝试过c++ 11的std::unordered_map,但似乎没有浮点对的标准哈希函数。这让我很惊讶,但又引出了另一个问题。Keep on topic:P
<标题>替代方案?Requeriments h1> 知道间隔库,如Boost interval和Boost interval Container库,但我需要一个解决方案,仅依赖于标准库设施

您可以使用二分查找O(lgn)复杂度。具体来说,下界形式#算法库。如果你有一个tuple <double, ptr_function>的向量,你可以使用二进制搜索它。如果range是特定的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)]

编辑:如果你想保留map,你可以使用map的下界

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