【问题标题】:Convert multimap<Key,Value> to vector<vector<Value>>将 multimap<Key,Value> 转换为 vector<vector<Value>>
【发布时间】:2015-04-12 20:08:53
【问题描述】:

我需要将std::unordered_multimap&lt;Key,T&gt; 转换为std::vector&lt;std::vector&lt;T&gt;&gt;。我需要这样做,因为我的程序需要对所有数据进行排序,而地图无法排序。一个例子:

// Map:
{ "A", 1 },
{ "A", 3 },
{ "A", 2 },
{ "B", 5 }, 
{ "B", 2 },

// Map converted to vector<vector<Value>>:
{ 1, 3, 2 }, 
{ 5, 2 }

现在我有这个有效的代码。但我想知道这是否是最好的方法。

#include <unordered_map>
#include <iostream>
#include <string>
#include <vector>    

int main()
{
    typedef std::string Key_t;
    typedef int Value_t;
    typedef std::unordered_multimap<Key_t, Value_t> Map_t;

    const Map_t map = {
        { "A", 1 }, 
        { "A", 3 }, 
        { "A", 2 },
        { "B", 5 }, 
        { "B", 2 },
    };

    std::vector< std::vector< Value_t > > output;

    for ( Map_t::const_iterator it = map.cbegin(); it != map.cend(); )
    {
        std::vector< Value_t > temp;
        const Map_t::const_iterator end = map.upper_bound( it->first );
        for ( ; it != end; ++it )
            temp.push_back( it->second );

        output.push_back( temp );
    }

    // Print the result
    for ( const std::vector< Value_t >& values : output )
    {
        for ( const Value_t& value : values )
            std::cout << value << " ";

        std::cout << std::endl;
    }
}

输出:

1 3 2
5 2

所以,现在我想知道是否有更快/更好的方法。

【问题讨论】:

  • 我认为typedef std::string Value_t; 应该是一个整数类型(例如,int)..
  • @JamesAdkison 哦,对。固定。
  • 不,再次检查,在unordered_mapunordered_multimap 的标准规范中没有upper_bound。确定您使用的是无序变体? (在修复缺少的&lt;vector&gt; 包含后,代码也无法使用 libstdc++ 或 libc++ 编译。)
  • unordered map 被记录为具有 equal_range 函数但没有上限或下限,这使得它依赖于排序顺序。
  • @Xeo 我 100% 确定我正在使用 unordered_multimap,并且我的代码正在 Visual Studio 2013 上编译和运行。

标签: c++ c++11 stl c++14


【解决方案1】:

这是我的尝试。

证据在这里:http://goo.gl/JVpHw9

#include <unordered_map>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{
    typedef std::string Key_t;
    typedef int Value_t;
    typedef std::unordered_multimap<Key_t, Value_t> Map_t;

    const Map_t map = {
        { "A", 1 }, 
        { "A", 3 }, 
        { "A", 2 },
        { "B", 5 }, 
        { "B", 2 },
    };

    std::vector< std::vector< Value_t > > output;

    for (auto it = map.begin(); it != map.end(); )
    {
        auto er = map.equal_range(it->first);
        auto tmp = std::vector< Value_t >{};
        for( ; it != er.second ; ++it) {
            tmp.push_back(it->second);
        };
        output.push_back(std::move(tmp));
    }
    // Print the result
    for ( const std::vector< Value_t >& values : output )
    {
        for ( const Value_t& value : values )
            std::cout << value << " ";

        std::cout << std::endl;
    }
}

【讨论】:

    【解决方案2】:

    通常的多地图迭代应该在这里工作:

    std::vector<std::vector<T>> out;
    
    for (auto it1 = m.begin(), it2 = it1, end = m.end(); it1 != end; it1 = it2)
    {
        out.emplace_back();
        for ( ; it1->first == it2->first; ++it2)
        {
            out.back().push_back(it2->second);
        }
    }
    

    【讨论】:

    • 为什么我们需要这个函数调用out.emplace_back();,难道仅仅out.push_back(it2->second)就足够了吗?
    • @Steephen:首先将一个空向量附加到向量的外部向量,然后将项目附加到该新的内部向量。
    • @Karrek SB 谢谢。
    【解决方案3】:

    以下作品适合我:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    
    int main () {
        std::unordered_multimap<std::string, int> map;
        map = {
            { "A", 1 }, 
            { "A", 3 }, 
            { "A", 2 },
            { "B", 5 }, 
            { "B", 2 },
        };
    
        std::vector<int> values;
    
        std::transform(map.begin(), map.end(),
                       std::back_inserter(values),
                       [](std::pair<std::string, int> element) {
                           return element.second;
                       });
    
        for (auto const& value : values) {
            std::cout << value << std::endl;
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-08
      • 2015-03-22
      • 2012-02-06
      • 1970-01-01
      • 2020-05-29
      • 2012-01-08
      • 2021-10-27
      相关资源
      最近更新 更多