Effective STL学习笔记--慎重选择删除元素的方法
- 要删除容器中有特定之的所有对象:
container<int> c;
如果容器是vector、string或deque,则使用erase-remove习惯用法
c.erase(remove(c.begin(), c.end(), 1999), c.end));//删除容器c(vector、string、deque)中所有值为1999的元素
如果容器是list,则使用list::remove。
c.remove(1999);
如果容器是一个标准关联容器,则使用它的erase成员函数。
c.erase(1999);
- 要删除容器中满足特定判别式(条件)的所有对象:
bool badValue(int);//返回x是否为“坏值”(要删除的值)
如果容器是vector、string或deque,则使用erase-remove_if习惯用法。
c.erase(remove_if(c.begin(), c.end(), badValue), c.end());
如果容器是list,则使用list::remove_if。
c.remove_if(badValue);
如果容器是一个标准关联容器,则使用remove_copy_if和swap,或者写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对它进行后缀递增。
方法1(易于编码,效率低)利用remove_copy_if把我们需要的值拷贝到一个新容器中,然后把原来容器的内容和新容器的内容相互交换。
AssocContainer<int> c;
AssocContainer<int> goodValues;//保存不被删除的值的临时容器
remove_copy_if(c.begin(), c.end(), inserter(goodValues, goodValues.end()), badValue);//把不被删除的值从c拷贝到goodValues中
c.swap(goodValues);//交换c和goodValues的内容
方法2(效率高)写一个循环来遍历c中的元素,并在遍历过程中删除元素。
for(AssocContainer<int>::iterator i = c.begin(); i != c.end(); ++ i)
{
if(badValue(*i)) c.erase(i ++);//一旦erase(i)返回,i就成了无效值,++i也就失效
else ++i;
}
- 要在循环内部做某些(除了删除对象之外的)操作:
ofstream logFile;//要写入的日志文件
AssocContainer<int> c;
如果容器是一个标准序列容器,则写一个循环来遍历容器中的元素,记住每次调用erase是,要用它的返回值更新迭代器。
for(SeqContainer<int>::iterator i = c.begin(); i != c.end(); ) //vector、string和deque
{
if(badValue(*i))
{
logFile << "Erasing " << *i << '\n';//写入日志文件
i = c.erase(i);//把erase的返回值赋给i,使i的值保持有效
}
else ++i;
}
如果容器是一个标准关联容器,则写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对迭代器做后缀递增。
for(AssocContainer<int>::iterator i = c.begin(); i != c.end(); )
{
if(badValue(*i))
{
logFile << "Erasing " << *i << '\n';//写入日志文件
c.erase(i ++);//删除元素
}
else ++i;
}
浙公网安备 33010602011771号