C++ map用法
C++ 中 map 提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值。
map的使用
- 需要导入头文件
#include <map> // STL头文件没有扩展名.h
- map对象是一个模版类,需要关键字和存储对象两个模版参数
std::map<int , std::string> person;
定义map类型,是有模板的,他接受三个参数:
第一个参数是键的数据类型
第二个参数是值的数据类型
第三个参数是排序规则,不写的话就按照默认的排序规则,也就是按照键的升序
- 可以对模版进行类型定义使其使用方便
typedef std::map<int , std::string> MAP_INI_STRING;
MAP_INI_STRING person;
map的构造
1、map 最基本的构造函数;
std::map<int , std::string> mapPerson;
2、map 添加数据;
- insert 函数插入 pair 数据
std::map < int , std::string > mapPerson;
mapPerson.insert(pair < int,string > (1,"Jim"));
2)insert 函数插入 value_type 数据
mapPerson.insert(std::map < int, std::string > ::value_type (2, "Tom"));
3)用数组方式插入数据
mapPerson[3] = "Jerry";
map数据的遍历
三种最常用的遍历方法:
1)前向迭代器
std::map < int ,std::string > ::iterator it;std::map < int ,std::string > ::iterator itEnd;it = mapPerson.begin();itEnd = mapPerson.end();while (it != itEnd) {cout<<it->first<<' '<<it->second<<endl; it++;
}
2)反向迭代器
std::map < int, string > ::reverse_iterator iter;
for(iter = mapPerson.rbegin(); iter != mapPerson.rend(); iter++) cout<<iter->first<<" "<<iter->second<<endl;
3)数组形式
mapPerson.insert(std::map<int, std::string>::value_type (1, "Tom"));
mapPerson[2] = "Jim";
mapPerson[3] = "Jerry";int nSize = mapPerson.size();
for(int n = 1; n <= nSize; n++)qDebug()<<QString::fromStdString(mapPerson[n]);
三种都是遍历,建议使用前向迭代器,慎用使用数组形式(角标开始位置谨慎)。
map中元素的查找
find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
map<int ,string > ::iterator l_it;; l_it = maplive.find(112);if(l_it == maplive.end())cout<<"we do not find 112"<<endl;else cout<<"wo find 112"<<endl;
map中元素的删除
如果删除112;
iterator erase(iterator it) ;//通过一个条目对象删除
iterator erase(iterator first,iterator last); //删除一个范围
size_type erase(const Key&key); //通过关键字删除
clear();//就相当于enumMap.erase(enumMap.begin(),enumMap.end());
map中swap的用法
Map中的swap不是一个容器中的元素交换,而是两个容器交换;
示例:
#include <map> #include <iostream>using namespace std;int main( ){map < int, int > m1, m2, m3;map < int, int >::iterator m1_Iter;m1.insert ( pair < int, int > ( 1, 10 ) );m1.insert ( pair < int, int > ( 2, 20 ) );m1.insert ( pair < int, int > ( 3, 30 ) );m2.insert ( pair < int, int > ( 10, 100 ) );m2.insert ( pair < int, int > ( 20, 200 ) );m3.insert ( pair < int, int > ( 30, 300 ) );cout << "The original map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter->second;cout << "." << endl;// This is the member function version of swap//m2 is said to be the argument map; m1 the target mapm1.swap( m2 );cout << "After swapping with m2, map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout << "." << endl;cout << "After swapping with m2, map m2 is:";for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout << "." << endl;// This is the specialized template version of swapswap( m1, m3 );cout << "After swapping with m3, map m1 is:";for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << " " << m1_Iter -> second;cout << "." << endl;
}
map的sort问题
Map中的元素是自动按key升序排序,所以不能对map用sort函数:
示例:
#include <map> #include <iostream>using namespace std;int main( ){map < int, int > m1;map < int, int >::iterator m1_Iter;m1.insert ( pair < int, int > ( 1, 20 ) );m1.insert ( pair < int, int > ( 4, 40 ) );m1.insert ( pair < int, int > ( 3, 60 ) );m1.insert ( pair < int, int > ( 2, 50 ) );m1.insert ( pair < int, int > ( 6, 40 ) );m1.insert ( pair < int, int > ( 7, 30 ) );cout << "The original map m1 is:"<<endl;for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )cout << m1_Iter->first<<" "<<m1_Iter->second<<endl;
}
map的基本操作函数
C++ Maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向 map 头部的迭代器clear() 删除所有元素count() 返回指定元素出现的次数empty() 如果 map 为空则返回 trueend() 返回指向 map 末尾的迭代器equal_range() 返回特殊条目的迭代器对erase() 删除一个元素find() 查找一个元素get_allocator() 返回map的配置器insert() 插入元素key_comp() 返回比较元素key的函数lower_bound() 返回键值>=给定元素的第一个位置max_size() 返回可以容纳的最大元素个数rbegin() 返回一个指向map尾部的逆向迭代器rend() 返回一个指向map头部的逆向迭代器size() 返回map中元素的个数swap() 交换两个mapupper_bound() 返回键值>给定元素的第一个位置value_comp() 返回比较元素value的函数
完整代码示例
#include<iostream>
using namespace std;
#include <map> // STL头文件没有扩展名.hmap<string, string> Country;
int main()
{int num;string key, value;cout << "请输入要添加的键值对个数:";cin >> num;cout << "\n";//========== 输入操作 ==========//用数组方式插入数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country[key] = value;}cout << "\n";/*//insert 函数插入 value_type 数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country.insert(map<string, string>::value_type(key, value));}cout << "\n";//insert函数插入pair数据for (int i = 0; i < num; i++){cout << "键:";cin >> key;cout << "值:";cin >> value;Country.insert(pair<string, string>(key, value));}cout << "\n";*///========== 输出操作 ==========/*//反向迭代器遍历输出map<string, string>::reverse_iterator iter;for (iter = Country.rbegin(); iter != Country.rend(); iter++)cout << iter->first << " " << iter->second << endl;//前向迭代器遍历输出map<string, string>::iterator it_Begin;it_Begin = Country.begin(); // begin() 返回指向map头部的迭代器map<string, string>::iterator it_End;it_End = Country.end(); //end() 返回指向 map 末尾的迭代器while (it_Begin != it_End){cout << it_Begin->first << " " << it_Begin->second << endl;it_Begin++;}*/return 0;
}
运行结果
前向迭代器输出:
反向迭代器输出:
说明:map中的元素是自动按key升序排序
用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值。
什么是vector?
在C++中,vector是一个十分有用的容器。它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
容器特性
1.顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
2.动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。提供了在序列末尾相对快速地添加/删除元素的操作。
3.能够感知内存分配器的(Allocator-aware)
容器使用一个内存分配器对象来动态地处理它的存储需求。
基本操作
- vector的声明及初始化
c++中必须要包含#include <vector>
#include <vector>
vector <T> vec; //T为各种数据类型,可以是基本类型,也可以是自己定义的数据类型
vector <T> vec[20]; //定义了一个二维数组,vec[i]就是一个vector<T>动态数组
不难看出看出vector是一个模板类
更多初始化方式:
vector<int> a; //声明一个int型向量a
vector<int> a(10); //声明一个初始大小为10的向量
vector<int> a(10, 1); //声明一个初始大小为10且初始值都为1的向量
vector<int> b(a); //声明并用向量a初始化向量b
vector<int> b(a.begin(), a.begin() + 3); //将a向量中从第0个到第2个(共3个)作为向量b的初始值
//也可以通过以下方式初始化
int n[] = { 1, 2, 3, 4, 5 };
vector<int> a(n, n + 5); //将数组n的前5个元素作为向量a的初值
vector<int> a(&n[1], &n[4]); //将n[1] - n[4]范围内的元素作为向量a的初值
- vector 输入输出及访问
直接用cin>>a[i];
或者cout<<a[i];
输入输出即可 - vector的遍历
第一种方式(类似于数组遍历):
vector<int> a;
for (int i = 0; i < a.size(); i++)
{cin >> a[i];cout << a[i];
}
第二种方式(vector迭代器遍历):
vector <int> a;
vector <int> ::iterator iter;
for (iter = a.begin(); iter != a.end(); iter++)
{cin >> *iter;cout << *iter;
}
第三种方式(利用反向迭代器遍历):
vector <int> a;
vector<int>::reverse_iterator iter;
for (iter = a.rbegin(); iter = a.rend(); iter++)
{cin >> *iter;cout << *iter;
}
- 向量vector的基本函数
vector <int> a;
vector <int> b;
1. a.size() :返回向量a中元素的个数
2. a.empty() : 判断向量a是否为空,空返回true
3. a.clear() : 清空向量a的所有元素
4.a.insert() : 向向量a中插入
a.insert(pos, 1000) : 将1000插入到向量a的pos位置上。例:a.insert(a.begin(), 1000);
a.insert(pos, n, 1000) :将1000分别插入到向量a的pos后n个位置上(包含pos)例:a.insert(a.begin(), 3, 1000);
b.insert(b.begin(), a.begin(), a.end()) : 将a.begin(), a.end()之间的全部元素插入到b.begin()前
5.a.erase : 删除向量a的元素
a.erase(pos) : 删除向量a中pos位置的元素
a.erase(st, ed) : 删除向量中从st到ed之间的元素
6.b.swap(a) : 交换a、b向量
7.比较以及复制
比较:保持 == 、 != 、 > 、 >= 、 < 、 <= 的惯有含义;
复制:b = a 将a复制一份赋给b
- 算法
(1) 使用reverse将元素翻转:需要头文件#include<algorithm>
reverse(vec.begin(),vec.end());
将元素翻转,即逆序排列!
(在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含)
(2)使用sort排序:需要头文件#include<algorithm>
,
sort(vec.begin(),vec.end());
(默认是按升序排列,即从小到大).
可以通过重写排序比较函数按照降序比较,如下:
定义排序比较函数:
bool Comp(const int &a,const int &b)
{return a>b;
}
调用时: sort(vec.begin(),vec.end(),Comp)
,这样就降序排序。
使用vector注意事项:
1、如果你要表示的向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低
2、vector作为函数的参数或者返回值时,需要注意它的写法:double Distance(vector<int>&a, vector<int>&b)
,其中的“&”绝对不能少!!!
补充:迭代器(Iterators)
迭代器类似于指针。通常,迭代器指向于容器(序列容器或关联容器)中的元素,因此,借助于迭代器,我们可以成功的访问容器中的各个元素。
迭代器中两个非常常用的操作时++(增量操作符)和*(取值操作符)。假设cntItr为某个容器的迭代器,那么如下语句:++cntItr;
,其结果为增加cntItr,使其指向容器中的下一个元素,相似的如下语句:*cntItr;
,访问cntItr指向的容器中的元素。