使用不包含在另一个向量中的键从地图中删除元素

时间:2014-11-30 11:15:03

标签: c++ map stl

给定一个stl容器,比如说std :: map:

std::map<int, CustomClass> some_container;
std::vector<int> real_objects; 

如何使用不在real_objects向量中的键正确有效地从some_container映射中删除每个元素?地图是否是此类任务的最佳容器?

1 个答案:

答案 0 :(得分:2)

我的第一直觉是批量删除非真实物体的块:

// Assuming real_objets is sorted (otherwise sort it)

auto first = some_container.begin();

for(int i : real_objects) {
  // end of the chunk to erase is the place where i could be
  // inserted without breaking the order
  auto last = some_container.lower_bound(i);

  some_container.erase(first, last);

  // if i is a key in the container, skip that element
  if(last != some_container.end() && last->first == i) {
    ++last;
  }

  first = last;
}

// and in the end, kill stuff that comes after real_objects.back()
some_container.erase(first, some_container.end());

这具有运行时复杂度O(n * log(m)),其中n为real_objects.size(),m为some_container.size(),这意味着如果some_container远大于{{{},则表现最佳1}}。否则,由于可以在线性时间内迭代real_objects,您可以按锁定步骤浏览并按顺序删除差异:

std::map

这具有运行时复杂度O(max(n,m)),因此如果// again, sort real_objects. if(!some_container.empty()) { // else there's nothing to do auto ir = real_objects.begin(); auto ire = std::lower_bound(real_objects.begin(), real_objects.end (), some_container.rbegin()->first); auto is = some_container.begin(); for(;;) { // find the next place where the real_objects and the keys of some_container don't match auto p = std::mismatch(ir, ire, is, [](int i, std::pair<int, int> const &p) { return i == p.first; }); if(p.first == real_objects .end() || p.second == some_container.end()) { // upon reaching the end, remove all that comes after the // end of real_objects (if anything) some_container.erase(p.second, some_container.end()); break; } else if(*p.first < p.second->first) { // if there's something in real_objects that's not in // some_container, skip it ++p.first; } else { // otherwise there's something in some_container that's // not in real_objects, so delete it. p.second = some_container.erase(p.second); } ir = p.first; is = p.second; } } some_container几乎匹配,它应该表现良好。