std :: map <string,string =“”>到字符串(第一个值)

时间:2016-09-18 08:43:36

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

我想创建std::string,其中包含std::map<std::string, std::string>的第一个元素,它们被某个分隔符分隔(可以来自STL或Boost)。 有没有比循环更好的解决方案(一行)?就像boost::algorithm::join的{​​{1}}一样。

4 个答案:

答案 0 :(得分:4)

这可以使用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

答案 1 :(得分:1)

你的算法应该是这样的:

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+=操作。

答案 2 :(得分:1)

作为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
$

答案 3 :(得分: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<std::string, std::string>