如何在遍历list,vector,map时删除符合条件的元素

本文详细介绍了如何使用代码操作实现特定数据结构的优化,并通过实例展示了如何在不同数据结构中进行元素的增删查改操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文转自http://www.cnblogs.com/CUCmehp/archive/2009/04/28/1445691.html


不多说了直接贴代码吧.

 

复制代码
class Pred{
public:
    
bool operator()(int a){
        
if(a>=6&&a<=7)
            
return true;
        
return false;
    }
};
void f(pair<int,int> p)
{
    cout
<<p.first<<" ";
}
int main(){
    
int a[]={1,2,3,4,5,6,7,8,9,10};
    list
<int> b=list<int>();
    b.assign(a,a
+10);
    vector
<int> d;
    d.assign(a,a
+10);
    map
<int,int> c=map<int,int>();
    
for(list<int>::iterator it=b.begin();it!=b.end();it++){
        c[
*it]=*it;
    }
    
//删除8,9
    for(list<int>::iterator it=b.begin();it!=b.end();){
        
if(*it>=8&&*it<10){
            it
=b.erase(it);
        }
else{
            it
++;
        }
    }
    
//删除5,6,注意这种写法只适应于list,不适应于vector,因为vector没有remove_if方法
    b.erase(remove_if(b.begin(),b.end(),Pred()),b.end());
    
//删除3,4
    for(vector<int>::iterator it=d.begin();it!=d.end();){
        
if(*it>=3&&*it<=4){
            it
=d.erase(it);
        }
else{
            it
++;
        }
    }

    ostream_iterator<int> os(cout," ");
    copy(b.begin(),b.end(),os);
    cout
<<endl;
    copy(d.begin(),d.end(),os);
    cout
<<endl;
    
//删除5,6
    for(map<int,int>::iterator it=c.begin();it!=c.end();){
        
if((*it).first>=5&&(*it).first<=6){
            c.erase(it
++);
        }
        
else{
            it
++;
        }
    }
    for_each(c.begin(),c.end(),f);
}
复制代码

<think>我们正在讨论如何在C++中遍历`vector<int>`并删除特定元素。根据引用内容,我们知道如何遍历vector,但删除元素需要特别注意迭代器的有效性。 删除元素,如果直接使用`erase`,会使当前迭代器失效。常见的做法是使用`erase`返回下一个有效的迭代器,或者使用“erase-remove”惯用法。 方法1:使用迭代器遍历删除(利用`erase`返回) 方法2:使用`std::remove`或`std::remove_if`算法(更高效,避免多次移动) 下面分别说明: ### 方法1:使用迭代器遍历删除遍历过程中,如果遇到需要删除元素,则调用`erase`,并将迭代器更新为`erase`返回的迭代器(指向下一个元素)。如果不需要删除,则递增迭代器。 示例:删除所有为3的元素 ```cpp #include <iostream> #include <vector> int main() { std::vector<int> myVector = {1, 2, 3, 4, 3, 5}; // 使用迭代器遍历 for (auto it = myVector.begin(); it != myVector.end(); ) { if (*it == 3) { it = myVector.erase(it); // erase返回下一个迭代器 } else { ++it; } } // 输出结果 for (const auto& element : myVector) { std::cout << element << " "; } return 0; } ``` ### 方法2:使用`std::remove`或`std::remove_if`(推荐) 这种方法更高效,因为`remove`会将不需要删除元素移到前面,然后返回一个指向新逻辑结尾的迭代器,最后我们再用`erase`删除从新逻辑结尾到实际结尾的元素。 示例:删除所有为3的元素 ```cpp #include <iostream> #include <vector> #include <algorithm> // 需要包含remove int main() { std::vector<int> myVector = {1, 2, 3, 4, 3, 5}; // 使用remove将所有不等于3的元素移到前面,并返回新的结束迭代器 auto newEnd = std::remove(myVector.begin(), myVector.end(), 3); // 删除从新结束位置到原结束位置的所有元素 myVector.erase(newEnd, myVector.end()); // 输出结果 for (const auto& element : myVector) { std::cout << element << " "; } return 0; } ``` 或者使用`remove_if`来删除满足条件的元素,例如删除所有偶数: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> myVector = {1, 2, 3, 4, 5, 6}; // 使用remove_if删除偶数 auto newEnd = std::remove_if(myVector.begin(), myVector.end(), [](int n) { return n % 2 == 0; }); myVector.erase(newEnd, myVector.end()); // 输出结果 for (const auto& element : myVector) { std::cout << element << " "; } return 0; } ``` 注意:方法2通常更高效,因为`remove`或`remove_if`只移动一次元素,而方法1在多次删除可能需要多次移动元素(每次删除后,后面的元素都要向前移动)。 总结: 1. 如果需要删除元素不多,可以使用方法1(迭代器+erase)。 2. 如果需要删除多个元素,推荐使用方法2(erase-remove惯用法),效率更高。 根据引用[1]和[4]中关于vector遍历和基本操作的内容,我们结合了删除操作。 请根据实际需求选择合适的方法。 §§相关问题§§ 1. 在C++中,vector的erase操作的间复杂度是多少? 2. 为什么使用`erase`后迭代器会失效?如何避免? 3. 除了vector,其他容器(如listmap)如何删除元素? 4. 在循环中删除元素,使用迭代器和反向迭代器有什么区别?</think>### 在C++中遍历删除vector<int>的指定元素 在C++中遍历`vector<int>`并删除特定元素,**必须谨慎处理迭代器失效问题**。以下是两种安全高效的方法: --- #### 方法1:使用`erase-remove`惯用法(推荐) ```cpp #include <vector> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 3, 4, 3, 5}; int target = 3; // 要删除元素 // 使用remove将目标元素移到末尾,返回新逻辑终点 auto newEnd = std::remove(vec.begin(), vec.end(), target); // 删除从新终点到实际终点的元素 vec.erase(newEnd, vec.end()); } ``` **原理**: 1. `std::remove`将非目标元素前移(间复杂度$O(n)$) 2. `erase`删除尾部无效元素间复杂度$O(1)$) 3. **优势**:高效且避免迭代器失效问题[^1][^4] --- #### 方法2:手动迭代删除(需更新迭代器) ```cpp #include <vector> int main() { std::vector<int> vec = {1, 2, 3, 4, 3, 5}; int target = 3; for (auto it = vec.begin(); it != vec.end(); ) { if (*it == target) { // erase返回被删元素的下一个迭代器 it = vec.erase(it); } else { ++it; // 仅当未删除递增 } } } ``` **关键点**: 1. 必须用`it = vec.erase(it)`接收返回 2. **禁止**在删除后直接`++it`(导致迭代器失效) 3. 适合带条件的复杂删除(如删除奇数): ```cpp if (*it % 2 != 0) it = vec.erase(it); ``` --- ### 重要注意事项 1. **迭代器失效**: - 删除元素会使当前位置之后的迭代器失效 - 未更新迭代器会导致未定义行为[^1][^4] 2. **性能对比**: | 方法 | 间复杂度 | 适用场景 | |------|------------|----------| | erase-remove | $O(n)$ | 批量删除特定 | | 手动迭代删除 | $O(n)$ | 复杂条件删除 | 3. **二维vector**: ```cpp std::vector<std::vector<int>> matrix; // 删除内层vector中的元素 for (auto& innerVec : matrix) { innerVec.erase(std::remove(innerVec.begin(), innerVec.end(), target), innerVec.end()); } ``` > 建议优先使用`erase-remove`惯用法,代码更简洁安全[^1][^4]。若需根据复杂条件删除,选择手动更新迭代器的方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值