C++ 从地图中删除键不包含在其他向量中的元素

C++ 从地图中删除键不包含在其他向量中的元素,c++,map,stl,C++,Map,Stl,给定一个stl容器,例如std::map: std::map<int, CustomClass> some_container; std::vector<int> real_objects; std::映射一些容器; std::向量实数对象; 如何正确有效地从某个容器映射中移除每个元素,其中键不在真实对象向量中?地图是执行此类任务的最佳容器吗?我的第一反应是批量擦除非真实对象块: // Assuming real_objets is sorted (otherwis

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

std::map<int, CustomClass> some_container;
std::vector<int> real_objects; 
std::映射一些容器;
std::向量实数对象;

如何正确有效地从某个容器映射中移除每个元素,其中键不在真实对象向量中?地图是执行此类任务的最佳容器吗?

我的第一反应是批量擦除非真实对象块:

// 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\u objects.size()
,m是
some\u container.size()
,这意味着如果
some\u container
real\u objects
大得多,则性能最佳。否则,由于可以在线性时间内迭代
std::map
,因此可以在锁定步骤中遍历这两个步骤,并按顺序删除差异:

// 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.empty()){//,则无需执行其他操作
auto ir=真实对象。begin();
auto-ire=std::下限(real\u objects.begin(),
real_objects.end(),
一些容器(container.rbegin()->first);
auto is=some_container.begin();
对于(;;){
//找到下一个真实\u对象与某些\u容器的键不匹配的位置
自动p=std::不匹配(ir,ire,is,[](int i,std::pair const&p){return i==p.first;});
if(p.first==real_objects.end()||
p、 second==some_container.end())
{
//到达终点后,移除所有在终点之后的物体
//真实对象的结尾(如果有)
some_container.erase(p.second,some_container.end());
打破
}否则如果(*p.firstfirst){
//如果在真实对象中有什么东西不在
//一些容器,跳过它
++p、 第一,;
}否则{
//否则,在某个容器中有某种东西
//不是在真实对象中,所以请删除它。
p、 秒=一些容器。擦除(p.second);
}
ir=p.first;
is=p.秒;
}
}

它的运行时复杂性为O(max(n,m)),因此如果
某个容器
真实对象
几乎匹配,它的性能应该会很好。

您可以使用适当的lambda尝试一些实现。我会说,首先在贴图和向量的关键点之间做一个设置差,然后删除剩下的部分。