给定一个主间隔,例如[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";
}
这个解决方案似乎有效,但我认为有一些小问题:
std::map
是否适合这项工作?:关联容器的目的是从键映射到值,但这里的映射键不是输入本身,是输入的处理形式(输入值所属的间隔)
我也尝试过C ++ 11的std::unordered_map
,但似乎没有浮点对的标准哈希函数。这让我感到惊讶,但又陷入了另一个问题。继续主题:P 我了解间隔库,例如Boost Interval和Boost Interval Container库,但我需要一个仅依赖于标准库设施的解决方案。
答案 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
是最大精度。