我有一组数据,其中一个整数映射到另一个整数,例如像这样
std::map<int,int> IE = { { -10, 85 }, { 0, 89 }, { 10, 92 }, { 20, 94 }, { 30, 98 } };
我想要做的是:给定任何整数作为输入值我想从地图中找到一对键,然后在值之间进行简单的插值(然后转换为int)。一个例子:
input: 25
surrounding keys: 20, 30
surrounding values: 94, 98
interpolated: 96
特殊情况:如果值低于第一个键,则返回第一个值,如果该值超出最后一个键,则返回最后一个值。
现在,经过一番思考后,我能想出的最好的代码是:
int interpolatedValue( int value, const std::map<int,int> &map )
{
// if we have exactly this value in the map, just return it
if( map.find(value) != map.end() ) return map.at(value);
// if we are beyond the limits, return the first/last element
if( value < map.begin()->first ) return map.begin()->second;
if( value > map.rbegin()->first ) return map.rbegin()->second;
auto lower = map.lower_bound(value) == map.begin() ? map.begin() : --( map.lower_bound(value)) ;
auto upper = map.upper_bound(value);
return int( lower->second + (upper->second - lower->second) * float(value-lower->first)/fabs(upper->first-lower->first) );
}
这正在做我想要的但是看起来像是一个如此简单的任务的暴行。是否有一种明显的,更优雅的方式来做到这一点(或者在我错过角落案例的情况下更正确)? 另外:是否有一种我错过的地图方法,可以找到所描述的那对密钥?
N.B。我发布的代码使用的是c ++ 11功能,但这根本不是必需的,所以我没有包含标签。