将一系列值映射到单个值

时间:2015-05-29 18:40:18

标签: c++ c++11

我需要将lowerBoundupperBound之间的值映射到某个值。

说明性示例:

例如,假设我有GPS系统,用户订阅了它。该系统能够为我提供用户与某一点的距离。根据用户的距离,我想为他们分配一个ID。

因此用户距离

  • 1100获取ID: 8.4
  • 101200获取ID: 7.2
  • 201300获取ID: 3.6
  • 401600获取ID: 4.1

依旧......

我的方法:

所以我做了什么,我通过如下初始化创建了std::map

   std::map<int, double> distanceToIdMap; 

   distanceToIdMap =
    {
            {100, 8.4},
            {200, 7.2},
            {300, 3.6},
    };

然后我使用此代码获取给定距离的ID:

double roundUpToHundred = std::ceil(realDistance / 100.0) * 100;
double powerForDistance = distanceToIdMap.at(roundUpToHundred);

然而,我的方法在401600距离时出现故障,因为距离为400+的天花板到最接近的100,我得到的值为500我在地图上没有条目。当然,简单的解决方案是将500的条目添加到distanceToIdMap,但这不是我想要处理此问题的方式。

我希望有一个{(lowerbound, upperbound) , correspondingID}结构的地图,以便我可以解决ID覆盖距离超过100米的情况。并且给定的可以检查lowerBound&lt; realDistance&lt; upperBound然后提供ID。

5 个答案:

答案 0 :(得分:4)

这听起来像std::lower_bound的用例。请注意,lower_bound是正确的实现,而不是upper_bound。此代码编译和工作。 map不需要排序,因为它已经排序。这应该在 O(log(N))

中运行

你需要抓住异常......

#include <iostream>
#include <algorithm>
#include <map>
#include <stdexcept>

using namespace std;

std::map<int, double> distanceToIdMap =
    {
            {100, 8.4},
            {200, 7.2},
            {300, 3.6},
            {600, 4.1}
    };   

double Distance(int user)
{
    auto x = std::lower_bound(distanceToIdMap.begin(), distanceToIdMap.end(), std::pair<const int,double>(user,0));
    if (x == distanceToIdMap.end()) throw std::runtime_error("can't find");
    return x->second;
}

int main()
{
    for(int user=25;user < 650;user+=25)
    {
        cout << user << " " << Distance(user) << std::endl;
    }
   return 0;
}

输出:

sh-4.3# g++ -o main *.cpp -std=c++11                                                                                                                                                                                                                    
main                                                                                                                                                                                                                                                    
sh-4.3# main                                                                                                                                                                                                                                            
25 8.4                                                                                                                                                                                                                                                  
50 8.4                                                                                                                                                                                                                                                  
75 8.4                                                                                                                                                                                                                                                  
100 8.4                                                                                                                                                                                                                                                 
125 7.2                                                                                                                                                                                                                                                 
150 7.2                                                                                                                                                                                                                                                 
175 7.2                                                                                                                                                                                                                                                 
200 7.2                                                                                                                                                                                                                                                 
225 3.6                                                                                                                                                                                                                                                 
250 3.6                                                                                                                                                                                                                                                 
275 3.6                                                                                                                                                                                                                                                 
300 3.6                                                                                                                                                                                                                                                 
325 4.1                                                                                                                                                                                                                                                 
350 4.1                                                                                                                                                                                                                                                 
375 4.1                                                                                                                                                                                                                                                 
400 4.1                                                                                                                                                                                                                                                 
425 4.1                                                                                                                                                                                                                                                 
450 4.1                                                                                                                                                                                                                                                 
475 4.1                                                                                                                                                                                                                                                 
500 4.1                                                                                                                                                                                                                                                 
525 4.1                                                                                                                                                                                                                                                 
550 4.1                                                                                                                                                                                                                                                 
575 4.1                                                                                                                                                                                                                                                 
600 4.1                                                                                                                                                                                                                                                 
terminate called after throwing an instance of 'std::runtime_error'                                                                                                                                                                                     
  what():  can't find                                                                                                                                                                                                                                   
Aborted (core dumped)                                                                                                                                                                                                                                   
sh-4.3# main                                                                                                                                                                                                                                            

答案 1 :(得分:2)

尝试upper_bound

 auto upper  = distanceToIdMap.upper_bound( 50 );
 std::cout << "value:" << upper->second << std::endl;

http://www.cplusplus.com/reference/map/map/upper_bound/

答案 2 :(得分:2)

使用std::map::lower_boundboost::optional,您可能会执行以下操作:

const std::map<int, boost::optional<double>> distanceToIdMap =
{
    {0, boost::none},
    {100, 8.4},
    {200, 7.2},
    {300, 3.6},
    {400, boost::none},
    {600, 4.1}
};

for (auto v : {-10, 50, 99, 100, 101, 250, 350, 500, 601})
{
    auto it = distanceToIdMap.lower_bound(v);

    if (it != distanceToIdMap.end() && it->second) {
        std::cout << v << " " << *it->second << std::endl;
    } else {
        std::cout << v << " None" << std::endl;
    }
}

Live example

答案 3 :(得分:1)

完全避免地图怎么样?

std::vector<std::pair<double, double>> table =
{
    {0, 0},
    {94.5, 2.1},
    {314.4, 4.7}
} ;

double distance = ...
double value = std::upper_bound(table.begin(), table.end(), std::pair(distance, 0)) ;

缺点:必须正确订购表格。

答案 4 :(得分:0)

这是一个简单的解决方案:

int mapdistance[] = {100,200,300};
double mapid[] = {8.4,7.2,3.6};
double dist=0;
for(int i=0;i<sizeof(mapdistance)/sizeof(int);i++) {
   dist += mapdistance[i];
   if (realdistance<=dist) return mapid[i];
}