stl map遍历和删除的方法

本文深入探讨C++ STL中的Map容器使用方法,包括遍历、查找、删除等关键操作,并对比不同实现方式的安全性和效率。

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


for(;iter!=mapStudent.end();)
{
     if((iter->second)>=aa)
     {
         //满足删除条件,删除当前结点,并指向下面一个结点
              mapStudent.erase(iter++);
     }
     else
     {
     //条件不满足,指向下面一个结点
     iter++;
     }
}
这种删除方式也是STL源码一书中推荐的方式,分析 mapStudent.erase(iter++)语句,map中在删除iter的时候,先将iter做缓存,然后执行iter++使之指向下一个结点,再进入erase函数体中执行删除操作,删除时使用的iter就是缓存下来的iter(也就是当前iter(做了加操作之后的iter)所指向结点的上一个结点)。
    根据以上分析,可以看出mapStudent.erase(iter++)和map Student.erase(iter); iter++;这个执行序列是不相同的。前者在erase执行前进行了加操作,在iter被删除(失效)前进行了加操作,是安全的;后者是在erase执行后才进行加操作,而此时iter已经被删除(当前的迭代器已经失效了),对一个已经失效的迭代器进行加操作,行为是不可预期的,这种写法势必会导致 map操作的失败并引起进程的异常。

数据的遍历

这里也提供三种方法,对map进行遍历

第一种:应用前向迭代器,上面举例程序中到处都是了,略过不表

第二种:应用反相迭代器,下面举例说明,要体会效果,请自个动手运行程序

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

       Map<int, string> mapStudent;

       mapStudent.insert(pair<int, string>(1, “student_one”));

       mapStudent.insert(pair<int, string>(2, “student_two”));

       mapStudent.insert(pair<int, string>(3, “student_three”));

       map<int, string>::reverse_iterator  iter;

       for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)

{

       Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

第三种:用数组方式,程序说明如下

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

       Map<int, string> mapStudent;

       mapStudent.insert(pair<int, string>(1, “student_one”));

       mapStudent.insert(pair<int, string>(2, “student_two”));

       mapStudent.insert(pair<int, string>(3, “student_three”));

       int nSize = mapStudent.size()

//此处有误,应该是 for(int nIndex = 1; nIndex <= nSize; nIndex++)


//by rainfish

       for(int nIndex = 0; nIndex < nSize; nIndex++)

{

       Cout<<mapStudent[nIndex]<<end;

}

}

5.       数据的查找(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

       Map<int, string> mapStudent;

       mapStudent.insert(pair<int, string>(1, “student_one”));

       mapStudent.insert(pair<int, string>(2, “student_two”));

       mapStudent.insert(pair<int, string>(3, “student_three”));

       map<int, string>::iterator iter;

       iter = mapStudent.find(1);

if(iter != mapStudent.end())

{

       Cout<<”Find, the value is ”<<iter->second<<endl;

}

Else

{

       Cout<<”Do not Find”<<endl;

}

}

第三种:这个方法用来判定数据是否出现,是显得笨了点,但是,我打算在这里讲解

Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)

Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)

例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3

Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

       Map<int, string> mapStudent;

       mapStudent[1] =  “student_one”;

       mapStudent[3] =  “student_three”;

       mapStudent[5] =  “student_five”;

       map<int, string>::iterator  iter;

iter = mapStudent.lower_bound(2);

{

       //返回的是下界3的迭代器

       Cout<<iter->second<<endl;

}

iter = mapStudent.lower_bound(3);

{

       //返回的是下界3的迭代器

       Cout<<iter->second<<endl;

}

 

iter = mapStudent.upper_bound(2);

{

       //返回的是上界3的迭代器

       Cout<<iter->second<<endl;

}

iter = mapStudent.upper_bound(3);

{

       //返回的是上界5的迭代器

       Cout<<iter->second<<endl;

}

 

Pair<map<int, string>::iterator, map<int, string>::iterator> mapPair;

mapPair = mapStudent.equal_range(2);

if(mapPair.first == mapPair.second)
       {

       cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl;
}

mapPair = mapStudent.equal_range(3);

if(mapPair.first == mapPair.second)
       {

       cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl;
}

}

6.       数据的清空与判空

清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map

7.       数据的删除

这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

       Map<int, string> mapStudent;

       mapStudent.insert(pair<int, string>(1, “student_one”));

       mapStudent.insert(pair<int, string>(2, “student_two”));

       mapStudent.insert(pair<int, string>(3, “student_three”));

 

//如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好

       //如果要删除1,用迭代器删除

       map<int, string>::iterator iter;

       iter = mapStudent.find(1);

       mapStudent.erase(iter);

 

       //如果要删除1,用关键字删除

       Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0

 

       //用迭代器,成片的删除

       //一下代码把整个map清空

       mapStudent.earse(mapStudent.begin(), mapStudent.end());

       //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合

 

       //自个加上遍历代码,打印输出吧

}


<think>好的,我现在需要帮助用户解决如何遍历C++ STL中的map的问题,并且提供示例代码。首先,我需要回忆一下关于C++ STL map的基本知识。 用户提到了几个引用内容,引用[1]中的代码展示了使用迭代器遍历map的例子,引用[3]提到了map的insert函数迭代器类型。所以用户可能需要基于这些引用来得到答案。 首先,遍历map的常见方法有哪些?我记得主要有两种:使用迭代器使用范围for循环。在C++11及以上版本中,范围for循环更为简洁。此外,用户可能需要知道如何访问键值,即使用迭代器的firstsecond成员。 接下来,我需要确认引用中的示例代码是否正确。比如,引用[1]中的代码用了传统的迭代器遍历,而引用[3]可能涉及insert操作,但遍历部分可能类似。要注意的是,map的迭代器是双向迭代器,不支持随机访问,所以不能像it+=2这样操作,这在引用[1]的代码注释中也有提到。 然后,用户需要示例代码,所以我要确保提供的代码正确无误。比如,使用begin()end()获取迭代器,循环中输出it->firstit->second。同时,C++11的范围for循环可以更简洁地实现同样的功能,是否也应该包括这种方法? 另外,用户可能对auto关键字的使用有疑问,是否需要说明?比如在范围for循环中使用auto&或者const auto&来遍历键值对,这样可以避免不必要的拷贝。 还需要考虑代码的完整性可编译性。比如,是否需要包含必要的头文件,如<iostream><map>,以及using namespace std;或者std::前缀的使用。不过,在示例代码中,用户可能更关注核心部分,所以可以适当简化,但需要指出必要的部分。 最后,根据用户提供的引用,特别是引用[1]中的示例,应该确保示例代码与之一致,同时补充其他方法如范围for循环。同时,注意回答的结构要清晰,分点说明不同的遍历方法,并给出对应的代码示例。 可能还需要检查是否有其他遍历方法,比如使用C++17的结构化绑定,但考虑到用户的引用中没有提到,可能暂时不涉及,或者简单提及。 总结步骤: 1. 介绍使用迭代器遍历,基于引用[1]中的例子。 2. 介绍C++11的范围for循环,更简洁的方法。 3. 提供示例代码,确保语法正确,并符合用户的引用内容。 4. 强调迭代器类型访问键值的方式。 5. 可能提到注意事项,如迭代器不支持随机访问(如it+=2会报错)。</think>### 如何遍历 C++ STL map 示例代码 在 C++ 中,遍历 `std::map` 主要通过 **迭代器** 或 **范围 for 循环** 实现。以下是具体方法及示例代码: --- #### 方法 1: 使用迭代器遍历 通过 `begin()` `end()` 获取迭代器,逐一遍历键值对。 **代码示例**: ```cpp #include <iostream> #include <map> using namespace std; int main() { map<string, int> simap = {{"apple", 5}, {"banana", 3}, {"orange", 7}}; // 使用迭代器遍历 map<string, int>::iterator it = simap.begin(); for (; it != simap.end(); ++it) { cout << it->first << " ==> " << it->second << endl; } return 0; } ``` **输出**: ``` apple ==> 5 banana ==> 3 orange ==> 7 ``` **说明**: - `it->first` 表示键(key),`it->second` 表示值(value)。 - 迭代器类型为 `std::map<Key, T>::iterator`,支持双向遍历(仅 `++` `--` 操作)[^1]。 --- #### 方法 2: 使用 C++11 范围 for 循环 利用 C++11 的自动类型推导简化遍历过程。 **代码示例**: ```cpp #include <iostream> #include <map> using namespace std; int main() { map<string, int> simap = {{"apple", 5}, {"banana", 3}, {"orange", 7}}; // 使用范围 for 循环遍历 for (const auto& pair : simap) { cout << pair.first << " ==> " << pair.second << endl; } return 0; } ``` **说明**: - `auto& pair` 自动推导为 `std::pair<const Key, T>&`,避免拷贝开销。 - 更简洁,适合现代 C++ 编码风格。 --- #### 注意事项 1. **键不可修改**:`map` 的键是 `const` 类型,禁止在遍历中修改键值[^3]。 2. **迭代器类型**:`std::map` 的迭代器是双向迭代器,不支持 `it += 2` 等随机访问操作。 3. **时间复杂度**:遍历的时间复杂度为 $O(n)$,与元素数量线性相关。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值