【问题标题】:C++ how to copy a map to a vector [duplicate]C ++如何将地图复制到矢量[重复]
【发布时间】:2010-10-15 15:07:10
【问题描述】:

在 C++ 中将一对从映射复制到向量的最佳方法是什么?我这样做是为了随后对向量进行排序。

【问题讨论】:

  • 地图已排序。您应该指定是否要对另一个参数或使用不同的键进行排序。否则问题是自我回答的:不要。
  • 关闭为副本,因为(较新的)副本质量更高,在一些人看来。

标签: c++ collections vector map


【解决方案1】:
vector<pair<K,V> > v(m.begin(), m.end());

vector<pair<K,V> > v(m.size());
copy(m.begin(), m.end(), v.begin());

copy()&lt;algorithm&gt; 中。

【讨论】:

  • 这个好像比较优雅简洁
  • 是的,这是最好的,尤其是第一个。只是一些解释 cmets:如果你有 typedef std::map&lt;K,V&gt; MapType 你不能声明向量 vector&lt;MapType::value_type&gt; 因为 value_type 是 pair&lt;const K, V&gt; 没有 operator= 并且不能被复制到向量中。此外,在第二个示例中,首先传递向量的大小(通过构造函数或保留)非常重要,因为复制不会在添加元素时在向量中分配空间,并且很有可能会遇到向量的初始分配结束。
  • copy(m.begin(), m.end(), v.begin()); 给了我一个分段错误。只是说。
  • @yasith 你需要保留vector的大小或者使用back_inserter()。
  • @DeepakMohanty 实际上你需要使用 vector::resize() 或 vector::reserve AND back_inserter()。
【解决方案2】:

这应该做你想做的:

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>

using namespace std;

bool cmp(const pair<int, int>  &p1, const pair<int, int> &p2)
{
    return p1.second < p2.second;
}

int main()
{
    map<int, int> m;
    for(int i = 0; i < 10; ++i)
        m[i] = i * -i;

    vector<pair<int, int> > v;
    copy(m.begin(), m.end(), back_inserter(v));

    sort(v.begin(), v.end(), cmp);

    for(int i = 0; i < v.size(); ++i)
        cout << v[i].first << " : " << v[i].second << endl;
    return 0;
}

【讨论】:

    【解决方案3】:

    如果您使用的是 std::map,它已经按键排序。只需创建一个迭代器并遍历从 begin() 到 end() 的地图即可。

    如果您想按地图键以外的其他内容进行排序,您可以使用相同的迭代器,并在遍历地图时将每个元素的副本推送到您的向量上。

    【讨论】:

    • 可能更简单:您可以在地图的 CTor 中指定比较器。
    【解决方案4】:

    假设您要复制键和值:

    std::map<Foo, Bar> m;
    
    
    // Map gets populated 
    // (...)
    
    
    // Copying it to a new vector via the constructor
    std::vector<std::pair<Foo, Bar>> v(m.begin(), m.end());
    
    
    // Copying it to an existing vector, erasing the contents
    v.assign(m.begin(), m.end());
    
    // Copying it to the back of an existing vector
    v.insert(v.end(), m.begin(), m.end());
    

    【讨论】:

    • 最后一个不正确。也许你的意思是 v.insert(v.rbegin().base(), m.begin(), m.end()); ?
    • whihelmtell - 为什么你认为它不正确?我刚试过 - 效果很好。
    • 想一想:v.rebegin().base() 返回与 v.end() 相同的迭代器
    • 如果 v.size() >= 1 应该没问题。范围是从位置迭代器之前的元素插入的。
    • 即使向量为空也没关系。在这种情况下 v.insert(v.end(), m_begin().m.end()) 与 v.insert(v.begin(), m_begin().m.end()) 相同,因为 v.开始()== v.end()。
    【解决方案5】:

    map 存储一对——一个键和一个值。您要复制哪个部分?或者,您要将两者都复制到两个不同的vectors 吗?

    我想复制两者。完成后,我需要弄清楚如何按对中的 second 值对向量进行排序。

    template <class V>
    struct sort_by_val {
      bool operator()(V const& l, V const& r) {
            return // ...
      }
    };
    
    vector<pair<K, V> > outv(map.begin(), map.end());
    
    sort(outv.begin(), outv.end(), sort_by_val());
    

    【讨论】:

    • 我想复制两个。完成后,我需要弄清楚如何按对中的 second 值对向量进行排序。
    • +1,清晰简单的解决方案。 @Jack:您确实应该将评论中的信息放入主要问题中,因为它高度相关-例如它会阻止每个人提到地图已经按它们的第一个元素排序。
    【解决方案6】:

    如果您的目的只是按类型而不是键进行排序,您可能需要查看Boost::Bimap。它允许您作为键访问映射对的两个部分。大概您可以像第一个键一样容易地按照第二个键的顺序对其进行迭代。

    【讨论】:

      【解决方案7】:

      您可以使用不同的地图(或集合)并在插入时使用转换进行排序:

      #include <map>
      #include <algorithm>
      
      typedef std::map<unsigned int, signed char> MapType1;
      typedef std::map<MapType1::mapped_type, MapType1::key_type> MapType2;
      
      struct SwapPair
      {
        MapType2::value_type operator()(MapType1::value_type const & v)
        {
          return std::make_pair (v.second, v.first);
        }
      };
      
      int main ()
      {
        MapType1 m1;
        for(int i = 0; i < 10; ++i)
          m1[i] = i * -i;
      
        MapType2 m2;
        std::transform (m1.begin ()
            , m1.end ()
            , std::inserter (m2, m2.end ())
            , SwapPair ());
      }
      

      我忘了补充一点,如果您经常需要这样做,那么使用 boost multi-index 容器可能会更好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-17
        • 1970-01-01
        • 2011-05-17
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多