【问题标题】:std::map<string, string> to string (first values)std::map<string, string> 到字符串(第一个值)
【发布时间】:2017-01-26 02:43:30
【问题描述】:

我想创建std::string,其中包含std::map&lt;std::string, std::string&gt; 的第一个元素,由一些分隔符分隔(它可以来自STL 或Boost)。 有没有比循环更好的解决方案(一行)?就像boost::algorithm::joinstd::vector&lt;std::string&gt;

【问题讨论】:

  • 不清楚。假设您有一个包含两个元素的地图。您正在寻找的输出类似于“key1 : value1, key2 : value2”?
  • How to retrieve all keys (or values) from a std::map?,修改解决方案追加到字符串
  • 不,@Rerito。对于:“key1:value1,key2:value2”和逗号分隔符我想要:“key1,key2”。

标签: c++ string c++11 dictionary boost


【解决方案1】:

如果你不想使用boost,那就试试std::accumulate:

const std::string delimiter = "#";
const std::string result = std::accumulate(M.begin(), M.end(), std::string(),
[delimiter](const std::string& s, const std::pair<const std::string, std::string>& p) {
    return s + (s.empty() ? std::string() : delimiter) + p.first;
});

在上面的代码中Mstd::map&lt;std::string, std::string&gt;

【讨论】:

  • value_type for Mpair&lt;const string, string&gt;。注意额外的const
  • 最好添加:#include
【解决方案2】:

这可以使用 Boost.Range 的 map_keys 和 Boost.StringAlgo 的 join 优雅地完成:

std::string get_keys(const std::map<std::string, std::string>& map) {
  return boost::algorithm::join(
    map | boost::adaptors::map_keys,
    ", ");
}

http://www.boost.org/doc/libs/1_61_0/boost/algorithm/string/join.hpp

http://www.boost.org/doc/libs/1_61_0/libs/range/doc/html/range/reference/adaptors/reference/map_keys.html

【讨论】:

    【解决方案3】:

    作为 M.M.正确指出,您可以为此使用boost::range(我添加了boost::string)。

    如果你的地图是m,那么最后一行

    std::vector<std::string> o;
    boost::copy(m | boost::adaptors::map_keys, std::back_inserter(o));
    boost::algorithm::join(o, ", ");
    

    是结果。 (不幸的是,这需要 大量 个头文件。)

    示例

    #include <boost/range/adaptor/map.hpp>
    #include <boost/range/algorithm/copy.hpp>
    #include <boost/assign.hpp>
    #include <boost/algorithm/string/join.hpp>
    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <vector>
    
    int main()
    {
        std::map<std::string, std::string> m;
        m["hello"] = "world";
        m["goodbye"] = "now";
    
        std::vector<std::string> o;
        boost::copy(m | boost::adaptors::map_keys, std::back_inserter(o));
        std::cout << boost::algorithm::join(o, ", ") << std::endl;
    }
    

    这个输出

    $ ./a.out 
    goodbye, hello
    $
    

    【讨论】:

      【解决方案4】:

      你的算法应该是这样的:

      std::string get_keys(const std::map<std::string, std::string>& map) {
        std::string result;
        std::for_each(map.cbegin(),
                      map.cend(),
                      [&result](const decltype(map)::value_type& p) {
                        result += p.first;
                        result += ", ";
                      });
      
        // Erase the last ", " from the string, if present
        if (result.size() > 0) {
          result.erase(result.size() - 2, 2);
        }
      
        return result;
      }
      

      基本上,您必须为地图中的每个元素循环并将其添加到字符串中。复杂度是 O(N),其中 N 是地图中元素的数量。

      您可以提高在字符串结果上应用reserve 的算法的性能。

      如果您知道字符串键的平均长度,您可以使用以下方法初始化变量:

      std::string result;
      result.reserve(map.size() * AVG_LENGTH_STR_KEY);
      

      这将大大改善循环中的operator+=操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-11
        • 2016-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多