c++ - 如果多映射中与其关联的 vector 为空,则删除该键

标签 c++ stl

最终,如果我试图删除与某个键关联的 vector 的所有元素,我会遇到段错误。我的预期输出是 new b new c new d new a,但我得到 new b new c new d 段错误。

    #include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

int main ()
{
  map<char,vector<char> > mmap; //multimap 
  char mychar[] = { 'b','c', 'd'};
  vector<char> vec (mychar,mychar+3);
  vector<char> newvec; 

  mmap.insert (pair<char,vector<char> >('a',vec)); //insert to multimap
  mmap.insert (pair<char,vector<char> >('b',vector<char>()));
  mmap.insert (pair<char,vector<char> >('c',vector<char>()));
  mmap.insert (pair<char,vector<char> >('d',vector<char>()));

  vector<char>::iterator veciter; 
  map<char,vector<char> >::iterator mapiter;

  for(int i=0;i<6;i++)
  {  
  for ( mapiter = mmap.begin(); mapiter != mmap.end(); ++mapiter) 
  {
    //if elements associated with vector of a key are empty the store the key in a new vector
    if(mapiter->second.empty()) 
    {
      newvec.push_back (mapiter->first);
      mmap.erase(mapiter);
    }
    else
    {
       for (veciter = mapiter->second.begin(); veciter != mapiter->second.end(); ++veciter)
       {
         //if an element of a vector of key is found in new vector, erase the element
         if (find(newvec.begin(), newvec.end(), *veciter)!=newvec.end())   
         {
            mapiter->second.erase(veciter);
         }

       }
    }
    // to display values of new vector     
    for (unsigned i=0; i<newvec.size(); ++i)
    cout << "new " << newvec[i]<<' ';
    cout << '\n'; 
  }  
  }

  return 0;
}

最佳答案

当您将迭代器传递给容器的删除函数时,该迭代器将失效。你需要考虑到这一点。假设,出于某种原因,std::removestd::remove_if 都不适合您的情况,标准习惯用法如下:

for (it = container.begin(); it != container.end(); /* no increment here */)
{
    if (should_be_removed(*it))
    {
        // possibly other operations involving the element we are about to remove
        it = container.erase(it);
    }
    else
    {
        // possibly other operations involving the element we chose not to remove
        ++it;
    }
}

当我们删除一个元素时,我们捕获删除操作的返回值,也就是下一个迭代器。否则,我们递增。请注意我为其他可能的操作留出空间的空间。如果没有其他操作,您应该可以使用 std::removestd::remove_if,结合容器的范围删除功能(需要两个迭代器)。

关于c++ - 如果多映射中与其关联的 vector 为空,则删除该键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13780886/

相关文章:

c++ - QTimer singleShot 使用激活器

c++ - 是否有一个函数可以将每个 double 转换为唯一的 uint64_t,同时保持精度和 ORDER? (为什么我找不到?)

c++ - STL 容器和算法 C++

c++ - 为什么 STL 双端队列不作为循环 vector 实现?

c++ - 使用 const 键类型引用调用 std::set of pointers 的 count 方法

c++ - std::unique 并从对象容器中删除重复项

c++ - 如何在 C++ 中向量化 for 循环?

c++ - 使用顶点缓冲对象渲染不同的三角形类型和三角形扇形? (OpenGL)

c++ - 在 C++ 中设置变量值之前检查变量是否更好?

c++ - std::transform 需要特别注意集合