代码之家  ›  专栏  ›  技术社区  ›  luca

如何在反向迭代时从多映射中擦除

c++
  •  0
  • luca  · 技术社区  · 4 年前

    如何从 std::multimap 同时对其进行反向迭代?

    正向迭代时擦除元素很简单,但反向迭代似乎需要更多的思考: multimap::erase 是正向迭代器,不能直接分配给循环中使用的反向迭代器。

    1 回复  |  直到 4 年前
        1
  •  0
  •   luca    4 年前

    这也适用于其他容器,而不仅仅是多映射:

    std::multimap<T1, T2> mmap = {...};
    
    for (auto it = mmap.rbegin(); it != mmap.rend();) {
      if ( ...condition...) {
        it = decltype(it)(mmap.erase(std::next(it).base()));
      } else {
        it++;
      }
    }
    

    示例代码:

    #include <iostream>
    #include <map>
    #include <set>
    
    void print(std::multimap<char, int> mmap) {
      std::cout << "mmap contains:\n";
      std::set<char> chars;
      for (auto kv : mmap)
        chars.insert(kv.first);
    
      for (char ch : chars) {
        auto ret = mmap.equal_range(ch);
        std::cout << ch << " =>";
        for (std::multimap<char, int>::iterator it = ret.first; it != ret.second;
             ++it)
          std::cout << ' ' << it->second;
        std::cout << '\n';
      }
    }
    
    int main() {
      std::multimap<char, int> mmap = {
          {'a', 10}, {'a', 20}, {'b', 30}, {'b', 40}, {'b', 50},
          {'c', 60}, {'c', 70}, {'d', 80}, {'d', 90},
      };
      print(mmap);
    
      for (auto it = mmap.rbegin(); it != mmap.rend();) {
        if (it->second == 70 || it->first == 'b') {
          it = decltype(it)(mmap.erase(std::next(it).base()));
          // more verbose alternative
          // it = std::reverse_iterator<decltype(mmap.begin())>(mmap.erase(std::next(it).base()));
        } else {
          it++;
        }
      }
    
      print(mmap);
    
      for (auto it = mmap.rbegin(); it != mmap.rend();) {
        it = decltype(it)(mmap.erase(std::next(it).base()));
        // more verbose alternative
        // it = std::reverse_iterator<decltype(mmap.begin())>(mmap.erase(std::next(it).base()));
      }
    
      print(mmap);
    
      return 0;
    }
    

    输出示例:

    mmap contains:
    a => 10 20
    b => 30 40 50
    c => 60 70
    d => 80 90
    mmap contains:
    a => 10 20
    c => 60
    d => 80 90
    mmap contains: