【问题标题】:C++ Printing lists with commas using reverse orderC++ 使用倒序用逗号打印列表
【发布时间】:2018-12-20 13:16:24
【问题描述】:

我在 C++ 中有以下代码

std::map<const std::string, JsonNode *>::iterator it;
std::map<const std::string, JsonNode *>::reverse_iterator last = vals.rbegin();
last++;

for (it = vals.begin(); it != vals.end(); it++){
    if (it == last.base())
    {
        str += it->first + ":" +it->second->toString();
    }else{
        str += it->first + ":" +it->second->toString() + ",";
    }
}

它工作得很好,但需要以相反的顺序来做同样的事情。 我就是这样开始的

std::map<const std::string, JsonNode *>::iterator first = vals.begin();
std::map<const std::string, JsonNode *>::reverse_iterator it;
first++;

for (it = vals.rbegin(); it != vals.rend(); it++){

    if (<condition>)
    {
        str += it->first + ":" +it->second->toString();
    }else{
        str += it->first + ":" +it->second->toString() + ",";
    }
}

但我不知道写什么好像条件

【问题讨论】:

  • base() 仅适用于std::map&lt;...&gt;::reverse_iterator。我正在寻找 std::map&lt;...&gt;::iterator 上的等价物

标签: c++ dictionary iterator reverse-iterator


【解决方案1】:

如果您将索引迭代器与--vals.rend() 进行比较,它应该可以工作。请参阅下面的示例。

#include <map>
#include <string>
#include <iostream>

using MyMap = std::map<const std::string, std::string>;

std::string f(MyMap const &vals)
{
  std::string str;
  MyMap::const_reverse_iterator it;
  MyMap::const_reverse_iterator first = --vals.rend();

  for (it = vals.rbegin(); it != vals.rend(); it++) {
    if (it == first) {
      str += it->first + ":" + it->second;
    } else {
      str += it->first + ":" + it->second + ",";
    }
  }

  return str;
}

int main()
{
  MyMap a{{"a", "b"}, {"c","d"}};

  std::cout << f(a) << "\n";
}

【讨论】:

    【解决方案2】:

    我终于用这个解决方案了

    std::map<const std::string, JsonNode *>::reverse_iterator it;
    for (it = vals.rbegin(); it != vals.rend(); it++){
        str += it->first + ":" +it->second->toString() + ",";
    }
    str.erase(str.size() - 1);
    

    谢谢。

    【讨论】:

      【解决方案3】:

      在第一个示例中,您不需要 reverse_iterator。你也应该使用stringstream,因为添加字符串效率很低。以下是我的做法:

      ostringstream stream(str);
      auto it = vals.begin();
      auto last = --vals.end();
      
      for (; it != vals.end(); it++) {
          if (it == last) {
              stream << it->first << ":" << it->second->toString();
          } else {
              stream << it->first << ":" << it->second->toString() << ",";
          }
      }
      
      str = stream.str();
      

      我假设您至少使用 C++11,如果您不是,那么只需将 auto 替换为实际类型。

      关于逆序,你可以在上面的例子中使用reverse_iterator而不是iterator,它也可以工作。

      【讨论】:

        【解决方案4】:

        如果你有一个ostream_joiner 迭代器(来自this answerstd::experimental),它变得非常简单

        std::stringstream ss;
        auto elem_to_string = [](MyMap::const_reference pair){ return pair.first + ":" + pair.second; };
        std::transform(vals.rbegin(), vals.rend(), make_ostream_joiner(ss, ","), elem_to_string);
        return ss.str();
        

        与非反向版本类似。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-31
          • 2021-07-20
          • 1970-01-01
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 2021-03-26
          相关资源
          最近更新 更多