如何从std :: map值的std :: vector中找到最小键值?

时间:2016-05-07 23:45:20

标签: c++ c++11 dictionary vector stl

我有std::vector std::map个值:

std::vector<std::map<std::string, double>> dataPoints;

我想找到最低的low值,74.0。这是我到目前为止的申请:

#include <vector>
#include <map>
#include <iostream>

int main() {
    std::vector<std::map<std::string, double>> dataPoints;

    dataPoints.push_back({{{"high", 77.0}, {"low", 74.0}}});
    dataPoints.push_back({{{"high", 78.0}, {"low", 75.0}}});
    dataPoints.push_back({{{"high", 79.0}, {"low", 76.0}}});
    dataPoints.push_back({{{"high", 80.0}, {"low", 77.0}}});
    dataPoints.push_back({{{"high", 81.0}, {"low", 78.0}}});

    return 0;
}

我到目前为止最接近的是:

double min = std::min_element(dataPoints.begin(), dataPoints.end(), [](std::map<std::string, double> &a, std::map<std::string, double> &b) { return (a["low"] < b["low"]); })["low"];

但这不太有用。

在JavaScript中,我可以按如下方式实现:

low = _.min(_.map(dataSegment, function(dataPoints) {
    return dataPoint.low;
}));

2 个答案:

答案 0 :(得分:6)

您需要min_element,而不是max_element。并且它返回一个迭代器,因此您需要取消引用它。

我想如果"low"不在地图中,你可能不想插入零。所以at代替[];这也使我们能够全面了解整个事情。

double min = std::min_element(dataPoints.cbegin(), dataPoints.cend(),
              [](const std::map<std::string, double> &a,
                 const std::map<std::string, double> &b) {
                     return a.at("low") < b.at("low"); 
              })->at("low");

答案 1 :(得分:1)

Map用于存储键/值对。如果您有2个始终相同的键,则无需使用地图。您也不需要对这些键进行排序。

如果给定第一个值为高和第二个低,则可以使用:

std::pair <double, double>

这样,每次添加新值时,都会保存两个std :: string大小的内存空间。

矢量用于存储无序序列。根据您是否希望对数据进行排序,您可以在此处使用一个基于高或低的比较。这将加速找到最小值到恒定时间。

集:

std::set <std::pair <double, double>>.

Set是一个已排序的容器。使用set,如果最低位于顶部,则可以使用 begin();如果位于底部,则可以结束()

如果您选择未排序,请使用 std :: vector 。如果您的容器经常更改且可能,那么您可能需要 std :: deque 。如果您的容器具有固定大小,并且您不打算对其进行修改,请使用 std :: array 。在这种情况下,您可以使用 min_element 。这种类型的搜索是线性时间。

修改

如果你想坚持使用std :: vector&lt;的std ::地图&LT; std :: string,double&gt;&gt;以下应该有效:

//min_element returns std::vector<std::map<std::string, double>>::iterator
auto minDataPoint = std::min_element(dataPoints.begin(), dataPoints.end(), [](std::map<std::string, double> &a, std::map<std::string, double> &b) { 
    return (a["low"] < b["low"]); 
});

std::cout<<"low "<<(*minDataPoint)["low"];

在此测试:http://ideone.com/sdG6fk