Ben*_*min 13 c++ algorithm containers stl map
我想删除我的std :: map中的一些元素.
我写了erase + remove_if技术,我总是使用其他序列容器.
但它不是用地图编译的.为什么?
我怎么能做这个工作?
std::map<int, int> m;
bool foo(const std::pair<int, int>& p)
{
return p.second > 15;
}
int _tmain(int argc, _TCHAR* argv[])
{
m.insert(make_pair(0, 0));
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.erase(
remove_if(m.begin(), m.end(), foo),
m.end()); // compile error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ale*_* C. 16
这样写一下map,因为它remove_if不适用于map迭代器(它只是将违规元素放在最后,而map迭代器不允许这样做):
template <typename Map, typename F>
void map_erase_if(Map& m, F pred)
{
typename Map::iterator i = m.begin();
while ((i = std::find_if(i, m.end(), pred)) != m.end())
m.erase(i++);
}
Run Code Online (Sandbox Code Playgroud)
或者如果你喜欢单行:
template <typename Map, typename F>
void map_erase_if(Map& m, F pred)
{
for (typename Map::iterator i = m.begin();
(i = std::find_if(i, m.end(), pred)) != m.end();
m.erase(i++));
}
Run Code Online (Sandbox Code Playgroud)
因为std::map不是"序列容器":)
remove_if会尝试将无用的元素放到地图的末尾,但这会导致违反地图的隐式数据结构(大多数情况下为红黑树).隐式数据结构定义了每个元素在地图中的位置,这就是remove_if不允许的原因std::map.
你应该std::map循环擦除一个接一个(或给出一些间隔)的元素.
有点像这样:
it = m.begin();
while ((it = std::find_if(it, m.end(), pred)) != m.end())
m.erase(it++);
Run Code Online (Sandbox Code Playgroud)
"使用其他序列容器"是您的错误 - map是一个关联容器!在关联容器中,元素由其键定义(而不是它们在序列容器中的插入顺序),并且您按键擦除元素:
m.erase(12);
Run Code Online (Sandbox Code Playgroud)
按键值擦除具有与查找相同的复杂度(例如,映射的O(log n),无序映射的O(1)等).或者,您可以在恒定时间内通过迭代器擦除.擦除迭代器会使迭代器无效,但不会使其他迭代器失效(再次与序列容器不同),因此如果要迭代地图,典型的习惯用法如下:
for (auto it = m.cbegin(); it != m.cend(); ) // no "++"!
{
if (it->second > 15) // your own condition goes here
{
m.erase(it++);
}
else
{
++it;
}
}
Run Code Online (Sandbox Code Playgroud)