【问题标题】:Sort maps by value in the specified order of key's priority按指定的键优先级顺序按值对映射进行排序
【发布时间】:2016-11-15 09:14:12
【问题描述】:

我有三个整数映射

std::map<string,int> map1;

map1["ymax"]=10;
map1["ymin"]=16;
map1["xval"]=10;

std::map<string,int> map2;

map2["ymax"]=16;
map2["ymin"]=20;
map2["xval"]=28;

std::map<string,int> map3;

map3["ymax"]=16;
map3["ymin"]=20;
map3["xval"]=10;

一张地图包含这张地图

std::map<string,std::map<string,int>> almap;

allmap["map1"]=map1;
allmap["map2"]=map2;
allmap["map3"]=map3; 

我想将最后一个地图排序为内部地图中的键 ymin,但如果在大地图中保持相等的地图我想排序为键 xval 然后作为键 ymax,同样的想法

allmap &gt;&gt; map1,map3,map2的正确排序

【问题讨论】:

  • if remain equal maps if what equal maps?

标签: c++ algorithm sorting stdmap


【解决方案1】:

创建所有映射的向量并通过tieing 他们的键对它们进行排序按照键的指定优先级的顺序

vector<map<string,int>> v{map1, map2, map3};

std::sort(v.begin(), v.end(), [](std::map<string,int> &lhs, std::map<string,int> &rhs){
                                 return tie(lhs["ymax"], lhs["ymin"], lhs["xval"]) < 
                                        tie(rhs["ymax"], rhs["ymin"], rhs["xval"]);}
          );

Live Demo

【讨论】:

    【解决方案2】:

    出于教育目的...

    std::map 要求键/值对中的键是不变的。它还要求密钥完全描述排序。

    allmap 的情况下,提供的键是std::string,这就是地图所要做的一切——即使是复杂的自定义比较功能。

    为了允许任何类型的排序,我们需要将外部名称和它们所代表的映射滚动到一个键对象中,然后对其进行排序。

    这开始争论要么使用一组对象(因为现在没有关联的数据),要么保留一个单独的、排序的键索引,按我们的自定义谓词排序。

    这是后者:

    #include <string>
    #include <map>
    #include <set>
    #include <vector>
    #include <utility>
    #include <algorithm>
    
    struct by_keys
    {
      template<class...Keys>
      by_keys(std::map<std::string, std::map<std::string, int>> const& allmap, Keys&&...keys) 
        : keys_ { std::forward<Keys>(keys)... }
      , allmap_(allmap)
      {
      }
    
      bool operator()(const std::string& ls, const std::string& rs) const
      {
        auto& l = allmap_.find(ls)->second; 
        auto& r = allmap_.find(rs)->second; 
        for (auto& key : keys_)
        {
          auto const& il = l.find(key);
          auto const& ir = r.find(key);
          if (il == std::end(l) && ir == std::end(r)) return false;
          if (il == std::end(l) && ir != std::end(r)) return true;
          if (il != std::end(l) && ir == std::end(r)) return false;
          if (*il < *ir) return true;
          if (*ir < *il) return false;
        }
        return false;
      }
    
      std::vector<std::string> keys_;
      std::map<std::string, std::map<std::string, int>> const& allmap_;
    };
    
    int main()
    {
    std::map<std::string,int> map1;
    
     map1["ymax"]=10;
     map1["ymin"]=16;
     map1["xval"]=10;
    
    std::map<std::string,int> map2;
    
     map2["ymax"]=16;
     map2["ymin"]=20;
     map2["xval"]=28;
    
    std::map<std::string,int> map3;
    
    map3["ymax"]=16;
    map3["ymin"]=20;
    map3["xval"]=10;
    
    std::map<std::string,std::map<std::string,int>> allmap;
    
    allmap["map1"]=map1;
    allmap["map2"]=map2;
    allmap["map3"]=map3; 
    
      // ok, now lets make an index into this map
    
      std::vector<std::string> sorted_keys;
      for (auto& entry : allmap) { sorted_keys.push_back(entry.first); }
      std::sort(std::begin(sorted_keys), std::end(sorted_keys), 
                by_keys(allmap, "ymin", "xval", "ymax"));
    
      // sorted_keys should now contain the names "map1", "map3", "map2" 
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-17
      • 1970-01-01
      • 2014-06-14
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      • 2022-11-11
      相关资源
      最近更新 更多