C++STL中list, vector, map, set用法与区别_c++ stl list map 比较

c.begin();                   返回指向容器最开始位置数据的指针

c.end();                      返回指向容器最后一个数据单元的指针+1

c.front();                     返回容器最开始单元数据的引用

c.back();                     返回容器最后一个数据的引用

c.max_size();              返回容器的最大容量

c.size();                      返回当前容器中实际存放元素的个数

c.capacity();               同c.size()

 c.resize();                   重新设置vector的容量

c.reserve();                同c.resize()

c.erase(p);               删除指针p指向位置的数据,返回下指向下一个数据位置的指针(迭代器)

c.erase(begin,end)     删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)

c.clear();                    清除所有数据

c.rbegin();                  将vector反转后的开始指针返回(其实就是原来的end-1)

c.rend();                     将vector反转后的结束指针返回(其实就是原来的begin-1)

c.empty();                   判断容器是否为空,若为空返回true,否则返回false

c1.swap(c2);               交换两个容器中的数据

c.insert(p,elem);          在指针p指向的位置插入数据elem,返回指向elem位置的指针       

c.insert(p,n,elem);      在位置p插入n个elem数据,无返回值

c.insert(p,begin,end) 在位置p插入在区间[begin,end)的数据,无返回值

3.vector中的操作



operator[] 如: c.[i];
同at()函数的作用相同,即取容器中的数据。


### 4.二维容器


C++ STLList队列用法(实例)  
 http://www.cnblogs.com/madlas/articles/1364503.html


C++ STL List队列用法(实例)



#include
#include
#include
#include

using namespace std;

//创建一个list容器的实例LISTINT
typedef list LISTINT;

//创建一个list容器的实例LISTCHAR
typedef list LISTCHAR;

void main(void)
{
//--------------------------
//用list容器处理整型数据
//--------------------------
//用LISTINT创建一个名为listOne的list对象
LISTINT listOne;
//声明i为迭代器
LISTINT::iterator i;

//从前面向listOne容器中添加数据
listOne.push_front (2);
listOne.push_front (1);

//从后面向listOne容器中添加数据
listOne.push_back (3);
listOne.push_back (4);

//从前向后显示listOne中的数据
cout<<"listOne.begin()--- listOne.end():"<<endl;
for (i = listOne.begin(); i != listOne.end(); ++i)
    cout << \*i << " ";
cout << endl;

//从后向后显示listOne中的数据

LISTINT::reverse_iterator ir;
cout<<“listOne.rbegin()—listOne.rend():”<<endl;
for (ir =listOne.rbegin(); ir!=listOne.rend();ir++) {
cout << *ir << " ";
}
cout << endl;

//使用STL的accumulate(累加)算法
int result = accumulate(listOne.begin(), listOne.end(),0);
cout<<"Sum="<<result<<endl;
cout<<"------------------"<<endl;

//--------------------------
//用list容器处理字符型数据
//--------------------------

//用LISTCHAR创建一个名为listOne的list对象
LISTCHAR listTwo;
//声明i为迭代器
LISTCHAR::iterator j;

//从前面向listTwo容器中添加数据
listTwo.push_front ('A');
listTwo.push_front ('B');

//从后面向listTwo容器中添加数据
listTwo.push_back ('x');
listTwo.push_back ('y');

//从前向后显示listTwo中的数据
cout<<"listTwo.begin()---listTwo.end():"<<endl;
for (j = listTwo.begin(); j != listTwo.end(); ++j)
    cout << char(\*j) << " ";
cout << endl;

//使用STL的max\_element算法求listTwo中的最大元素并显示
j=max\_element(listTwo.begin(),listTwo.end());
cout << "The maximum element in listTwo is: "<<char(\*j)<<endl;

}



#include
#include

using namespace std;
typedef list INTLIST;

//从前向后显示list队列的全部元素
void put_list(INTLISTlist, char *name)
{
INTLIST::iterator plist;

cout << "The contents of " << name << " : ";
for(plist = list.begin(); plist != list.end(); plist++)
    cout << \*plist << " ";
cout<<endl;

}

//测试list容器的功能
void main(void)
{
//list1对象初始为空
INTLIST list1;
//list2对象最初有10个值为6的元素
INTLIST list2(10,6);
//list3对象最初有3个值为6的元素
INTLIST list3(list2.begin(),–list2.end());

//声明一个名为i的双向迭代器
INTLIST::iterator i;

//从前向后显示各list对象的元素
put\_list(list1,"list1");
put\_list(list2,"list2");
put\_list(list3,"list3");

//从list1序列后面添加两个元素
list1.push_back(2);
list1.push_back(4);
cout<<“list1.push_back(2) andlist1.push_back(4):”<<endl;
put_list(list1,“list1”);

//从list1序列前面添加两个元素
list1.push_front(5);
list1.push_front(7);
cout<<“list1.push_front(5) andlist1.push_front(7):”<<endl;
put_list(list1,“list1”);

//在list1序列中间插入数据
list1.insert(++list1.begin(),3,9);
cout<<“list1.insert(list1.begin()+1,3,9):”<<endl;
put_list(list1,“list1”);

//测试引用类函数
cout<<“list1.front()=”<<list1.front()<<endl;
cout<<“list1.back()=”<<list1.back()<<endl;

//从list1序列的前后各移去一个元素
list1.pop_front();
list1.pop_back();
cout<<“list1.pop_front() andlist1.pop_back():”<<endl;
put_list(list1,“list1”);

//清除list1中的第2个元素
list1.erase(++list1.begin());
cout<<“list1.erase(++list1.begin()):”<<endl;
put_list(list1,“list1”);

//对list2赋值并显示
list2.assign(8,1);
cout<<“list2.assign(8,1):”<<endl;
put_list(list2,“list2”);

//显示序列的状态信息
cout<<"list1.max_size(): "<<list1.max_size()<<endl;
cout<<"list1.size(): "<<list1.size()<<endl;
cout<<"list1.empty(): "<<list1.empty()<<endl;

//list序列容器的运算
put_list(list1,“list1”);
put_list(list3,“list3”);
cout<<"list1>list3: "<<(list1>list3)<<endl;
cout<<"list1<list3: "<<(list1<list3)<<endl;

//对list1容器排序
list1.sort();
put_list(list1,“list1”);

//结合处理
list1.splice(++list1.begin(),list3);
put_list(list1,“list1”);
put_list(list3,“list3”);
}


### C++map


映照容器  
 http://www.cppblog.com/vontroy/archive/2010/05/16/115501.html


map映照容器的元素数据是一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。  
 map映照容器的数据结构是采用红黑树来实现的,插入键值的元素不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。  
 使用map容器需要头文件包含语句“#include”,map文件也包含了对multimap多重映照容器的定义。


1、map创建、元素插入和遍历访问  
      创建map对象,键值与映照数据的类型由自己定义。在没有指定比较函数时,元素的插入位置是按键值由小到大插入到黑白树中去的,下面这个程序详细说明了如何操作map容器。



#include
#include
#include

using std :: cout ;
using std :: endl ;
using std :: string ;
using std :: map ;

int main()
{
//定义map对象,当前没有任何元素
map<string,float> m ;

 //插入元素,按键值的由小到大放入黑白树中
 m["Jack"] = 98.5 ;
 m["Bomi"] = 96.0 ;
 m["Kate"] = 97.5 ;
 
//先前遍历元素
 map<string,float> :: iterator it ;
 for(it = m.begin() ; it != m.end() ; it ++)
      cout << (\*it).first << " : " << (\*it).second << endl ;

 return 0 ;

}

// 运行结果:
Bomi :96
Jack :98.5
Kate :97.5


程序编译试,会产生代号为“warning C4786” 的警告, “4786” 是标记符超长警告的代号。可以在程序的头文件包含代码的前面使用"#pragma waring(disable:4786)" 宏语句,强制编译器忽略该警告。4786号警告对程序的正确性和运行并无影响。  
 2、删除元素  
      map映照容器的 erase() 删除元素函数,可以删除某个迭代器位置上的元素、等于某个键值的元素、一个迭代器区间上的所有元素,当然,也可使用clear()方法清空map映照容器。  
 下面这个程序演示了删除map容器中键值为28的元素:



#include
#include
#include

using std :: cout ;
using std :: endl ;
using std :: string ;
using std :: map ;

int main()
{
//定义map对象,当前没有任何元素
map<int, char> m ;
//插入元素,按键值的由小到大放入黑白树中
m[25] = ‘m’ ;
m[28] = ‘k’ ;
m[10] = ‘x’ ;
m[30] = ‘a’ ;
//删除键值为28的元素
m.erase(28) ;
//向前遍历元素
map<int, char> :: iterator it ;
for(it = m.begin() ; it != m.end() ; it ++)
{
//输出键值与映照数据
cout << (*it).first << " : " << (*it).second << endl ;
}
return 0 ;
}


运行结果:



10 : x
25 : m
30 : a


3、元素反向遍历  
      可以用反向迭代器reverse\_iterator反向遍历map映照容器中的数据,它需要rbegin()方法和rend()方法指出反向遍历的起始位置和终止位置。



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10int main()
11{
12 //定义map对象,当前没有任何元素
13 map<int, char> m ;
14 //插入元素,按键值的由小到大放入黑白树中
15 m[25] = ‘m’ ;
16 m[28] = ‘k’ ;
17 m[10] = ‘x’ ;
18 m[30] = ‘a’ ;
19 //反向遍历元素
20 map<int, char> :: reverse_iterator rit ;
21 for( rit = m.rbegin() ; rit != m.rend() ; rit ++)
22 {
23 //输入键值与映照数据
24 cout << (*rit).first << " : " << (*rit).second << endl ;
25 }
26 return 0 ;
27}
28


运行结果:



              30 : a
              28 : k
              25 : m
              10 : x

4、元素的搜索  
     使用find()方法来搜索某个键值,如果搜索到了,则返回该键值所在的迭代器位置,否则,返回end()迭代器位置。由于map采用黑白树数据结构来实现,所以搜索速度是极快的。  
 下面这个程序搜索键值为28的元素:



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10int main()
11{
12 //定义map对象,当前没有任何元素
13 map<int, char> m ;
14 //插入元素,按键值的由小到大放入黑白树中
15 m[25] = ‘m’ ;
16 m[28] = ‘k’ ;
17 m[10] = ‘x’ ;
18 m[30] = ‘a’ ;
19 map<int, char> :: iterator it ;
20 it = m.find(28) ;
21 if(it != m.end()) //搜索到该键值
22 cout << (*it).first << " : " << ( *it ).second << endl ;
23 else
24 cout << “not found it” << endl ;
25 return 0 ;
26}


5、自定义比较函数  
     将元素插入到map中去的时候,map会根据设定的比较函数将该元素放到该放的节点上去。在定义map的时候,如果没有指定比较函数,那么采用默认的比较函数,即按键值由小到大的顺序插入元素。在很多情况下,需要自己编写比较函数。  
 编写方法有两种。  
     (1)如果元素不是结构体,那么,可以编写比较函数。下面这个程序编写的比较规则是要求按键值由大到小的顺序将元素插入到map中



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10//自定义比较函数 myComp
11struct myComp
12{
13 bool operator() (const int &a, const int &b)
14 {
15 if(a != b) return a > b ;
16 else return a > b ;
17 }
18} ;
19
20int main()
21{
22 //定义map对象,当前没有任何元素
23 map<int, char> m ;
24 //插入元素,按键值的由小到大放入黑白树中
25 m[25] = ‘m’ ;
26 m[28] = ‘k’ ;
27 m[10] = ‘x’ ;
28 m[30] = ‘a’ ;
29 //使用前向迭代器中序遍历map
30 map<int, char,myComp> :: iterator it ;
31 for(it = m.begin() ; it != m.end() ; it ++)
32 cout << (*it).first << " : " << (*it).second << endl ;
33 return 0 ;
34}


运行结果:



              30 :a
              28 :k
              25 :m
              10 :x

(2)如果元素是结构体,那么,可以直接把比较函数写在结构体内。下面的程序详细说明了如何操作:



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10struct Info
11{
12 string name ;
13 float score ;
14 //重载 “<”操作符,自定义排列规则
15 bool operator < (const Info &a) const
16 {
17 //按score由大到小排列。如果要由小到大排列,使用“>”号即可
18 return a.score < score ;
19 }
20} ;
21
22int main()
23{
24 //定义map对象,当前没有任何元素
25 map<Info, int> m ;
26 //定义Info结构体变量
27 Info info ;
28 //插入元素,按键值的由小到大放入黑白树中
29 info.name = “Jack” ;
30 info.score = 60 ;
31 m[info] = 25 ;
32 info.name = “Bomi” ;
33 info.score = 80 ;
34 m[info] = 10 ;
35 info.name = “Peti” ;
36 info.score = 66.5 ;
37 m[info] = 30 ;
38 //使用前向迭代器中序遍历map
39 map<Info,int> :: iterator it ;
40 for(it = m.begin() ; it != m.end() ; it ++)
41 {
42 cout << (*it).second << " : " ;
43 cout << ((*it).first).name << " : " << ((*it).first).score << endl ;
44 }
45 return 0 ;
46}


运行结果:



10 :Bomi 80
30 :Peti 66.5
25 :Jack 60


6、用map实现数字分离  
     对数字的各位进行分离,采用取余等数学方法是很耗时的。而把数字当成字符串,使用map的映照功能,很方便地实现了数字分离。下面这个程序将一个字符串中的字符当成数字,并将各位的数值相加,最后输出各位的和。



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10int main()
11{
12 //定义map对象,当前没有任何元素
13 map<char, int> m ;
14
15 //赋值:字符映射数字
16 m[‘0’] = 0 ;
17 m[‘1’] = 1 ;
18 m[‘2’] = 2 ;
19 m[‘3’] = 3 ;
20 m[‘4’] = 4 ;
21 m[‘5’] = 5 ;
22 m[‘6’] = 6 ;
23 m[‘7’] = 7 ;
24 m[‘8’] = 8 ;
25 m[‘9’] = 9 ;
26 /**//*上面的10条赋值语句可采用下面这个循环简化代码编写
27 for(int j = 0 ; j < 10 ; j++)
28 {
29 m[‘0’ + j] = j ;
30 }
31 */
32 string sa, sb ;
33 sa = “6234” ;
34 int i ;
35 int sum = 0 ;
36 for ( i = 0 ; i < sa.length() ; i++ )
37 sum += m[sa[i]] ;
38 cout << "sum = " << sum << endl ;
39 return 0 ;
40}


7、数字映照字符的map写法  
      在很多情况下,需要实现将数字映射为相应的字符,看看下面的程序:



1#include
2#include
3#include
4
5using std :: cout ;
6using std :: endl ;
7using std :: string ;
8using std :: map ;
9
10int main()
11{
12 //定义map对象,当前没有任何元素
13 map<int, char> m ;
14
15 //赋值:字符映射数字
16 m[0] = ‘0’ ;
17 m[1] = ‘1’ ;
18 m[2] = ‘2’ ;
19 m[3] = ‘3’ ;
20 m[4] = ‘4’ ;
21 m[5] = ‘5’ ;
22 m[6] = ‘6’ ;
23 m[7] = ‘7’ ;
24 m[8] = ‘8’ ;
25 m[9] = ‘9’ ;
26 /**//*上面的10条赋值语句可采用下面这个循环简化代码编写
27 for(int j = 0 ; j < 10 ; j++)
28 {
29 m[j] = ‘0’ + j ;
30 }
31 */
32 int n = 7 ;
33 string s = "The number is " ;
34 cout << s + m[n] << endl ;
35 return 0 ;
36}


运行结果:



The number is 7


准模板库就是类与函数模板的大集合。STL共有6种组件:容器,容器适配器,迭代器,算法,函数对象和函数适配器。  
 1、容器:


容器是用来存储和组织其他对象的对象。STL容器类的模板在标准头文件中定义。主要如下所示


①序列容器


基本的序列容器是上面图中的前三类:


关于三者的优缺点主要是:


A:vector矢量容器:可以随机访问容器的内容,在序列末尾添加或删除对象,但是因为是从尾部删除,过程非常慢,因为必须移动插入或删除点后面的所有对象。


矢量容器的操作:(自己以前有个表,贴出来大家看看)


其中的capacity表示容量,size是当前数据个数。矢量容器如果用户添加一个元素时容量已满,那么就增加当前容量的一半的内存,比如现在是500了,用户添加进第501个,那么他会再开拓250个,总共就750个了。所以矢量容器当你添加数据量很大的时候,需要注意这一点哦。。。


如果想用迭代器访问元素是比较简单的,使用迭代器输出元素的循环类似如下:


vector::iterator表示矢量容器vector的迭代器。。。  
 for(vector::iterator iter = number.begin(); iter<number.end(); iter++)//这里的iterator iter算是一个指针了  
 cout << " " << \*iter;  
 当然也可以用我们自己的方法,但是感觉用上面的更好一些。


for(vector::size\_type i=0; i<number.size(); i++)  
 cout << " " << number[i]


排序矢量元素:


对矢量元素的排序可以使用头文件中定义的sort()函数模板来对一个矢量容器进行排序。但是有几点要求需要注意


sort()函数模板用<运算符来排列元素的顺序,所以容器中对象必须可以进行<运算,如果是基本类型,可以直接调用sort(),如果是自定义对象,必须对<进行运算符重载  
 两个迭代器的指向必须是序列的第一个对象和最后一个对象的下一个位置。比如:sort(people.begin(), people.end());//这里两个参数就是迭代器的意思了


B:deque容器:非常类似vector,且支持相同的操作,但是它还可以在序列开头添加和删除。


deque双端队列容器与矢量容器基本类似,具有相同的函数成员,但是有点不同的是它支持从两端插入和删除数据,所以就有了两个函数:push\_front和pop\_front。并且有两个迭代器变量


#include   
 deque data;//创建双端队列容器对象  
 deque::iterator iter;//书序迭代器  
 deque::reverse\_iterator riter;//逆序迭代器。  
 //iter和riter是不同的类型


C:list容器是双向链表,因此可以有效的在任何位置添加和删除。列表的缺点是不能随机访问内容,要想访问内容必须在列表的内部从头开始便利内容,或者从尾部开始。


②关联容器


map<K, T>映射容器:K表示键,T表示对象,根据特定的键映射到对象,可以进行快速的检索。


有关它的创建以及查找的操作作如下总结


//创建映射容器  
 map<person, string> phonebook;


//创建要存储的对象  
 pair<person, string> entry = pair<person, string>(person(“mel”, “Gibson”), “213 345 567”);


//插入对象  
 phonebook.insert(entry);//只要映射中没有相同的键,就可以插入entry


//访问对象  
 string number = phonebook[person(“mel”, “Gibson”)];//如果这个键不存在,会默认将这个键插入


//如果不想在找不到的时候插入,可以先查找然后再检索  
 person key = person(“mel”, “Gibson”);  
 map<person, string>::iterator iter = phonebook.find(key);//创建迭代器,就认为是指针就好了


if(iter != phonebook.end())  
 string number = iter->second;


2、容器适配器:


容器适配器是包装了现有的STL容器类的模板类,提供了一个不同的、通常更有限制性的功能。具体如下所示


A:queue队列容器:通过适配器实现先进先出的存储机制。我们只能向队列的末尾添加或从开头删除元素。push\_back() pop\_front()


代码:queue<string, list > names;(这就是定义的一个适配器)是基于列表创建队列的。适配器模板的第二个类型形参指定要使用的底层序列容器,主要的操作如下


B:priority\_queue优先级队列容器:是一个队列,它的顶部总是具有最大或最高优先级。优先级队列容器与队列容器一个不同点是优先级队列容器不能访问队列后端的元素。


默认情况下,优先级队列适配器类使用的是矢量容器vector,当然可以选择指定不同的序列容器作为基础,并选择一个备用函数对象来确定元素的优先级代码如下


priority\_queue<int, deque, greate> numbers;


C:stack堆栈容器:其适配器模板在头文件中定义,默认情况下基于deque容器实现向下推栈,即后进先出机制。只能访问最近刚刚进去的对象


//定义容器  
 stack people;  
 //基于列表来定义堆栈  
 stack<string, list> names;


基本操作如下:


3、迭代器:


具体它的意思还没怎么看明白,书上介绍迭代器的行为与指针类似,这里做个标记奋斗,看看后面的例子再给出具体的解释


具体分为三个部分:输入流迭代器、插入迭代器和输出流迭代器。


、


看这一章的内容看的我有点抑郁了都,摘段课本介绍的内容,还是可以帮助理解的


头文件中定义了迭代器的几个模板:①流迭代器作为指向输入或输出流的指针,他们可以用来在流和任何使用迭代器或目的地之间传输数据。②插入迭代器可以将数据传输给一个基本序列容器。头文件中定义了两个流迭代器模板:istream\_iterator用于输入流,ostream\_iterator用于输出流。T表示从流中提取数据或写到流中的对象的类型。头文件还定义了三个插入模板:insert, back\_insert和front\_inset。其中T也是指代序列容器中数据的类型。


输入流迭代器用下面的程序来说明下,可见具体注释


#include   
 #include   
 #include   
 #include 


using namespace std;


int main()  
 {  
 //定义矢量容器  
 vector numbers;  
 cout << “请输入整数值,以字母结束:”;



//定义输入流迭代器。注意两个不同
//1、numberInput(cin)是指定迭代器指向流cin
//2、numbersEnd没有指定,是默认的,默认构造了一个end_of_stream的迭代器,它等价于调用end()
istream_iterator numbersInput(cin), numbersEnd;

//用户输入,直到输入的不是int类型或者终止时结束。
while(numbersInput != numbersEnd)
numbers.push_back(*numbersInput++);

cout << “打印输出:” << numbers.at(3) << endl;

//如何指定输入流呢?

//确定字符串
string data(“2.1 3.6 36.5 26 34 25 2.9 63.8”);

//指定data为输入流input。需要头文件
istringstream input(data);

//定义迭代器
istream_iterator begin(input), end;

//计算数值和。
//acculumate为头文件下定义的函数。
//第一个参数是开始迭代器,第二个是终止迭代器(最后一个值的下一个)。第三个是和的初值,注意必须用0.0,用它确定数据类型是double
cout << “打印数据的总和:” << accumulate(begin, end, 0.0) << endl;


}  
 输出结果:


耽误时间太多。以后再写吧


4、算法:


算法是操作迭代器提供的一组对象的STL函数模板,对对象的一个操作,可以与前面的容器迭代器结合起来看。如下图介绍


5、函数对象:


函数对象是重载()运算符的类类型的对象。就是实现operator()()函数。


函数对象模板在头文件中定义,必要时我们也可以定义自己的函数对象。做个标记奋斗,等有具体实例来进行进一步的解释。


6、函数适配器:


函数适配器是允许合并函数对象以产生一个更复杂的函数对象的函数模板。


Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。


下面举例说明什么是一对一的数据映射。比如一个班级中,每个学生的学号跟他的姓名就存在着一一映射的关系,这个模型用map可能轻易描述,很明显学号用int描述,姓名用字符串描述(本篇文章中不用char \*来描述字符串,而是采用STL中string来描述),下面给出map描述代码:


Map<int, string> mapStudent;


1. ```
  map的构造函数

map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

Map<int, string> mapStudent;

数据的插入



在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:


第一种:用insert函数插入pair数据,下面举例说明(以下代码虽然是随手写的,应该可以在VC和GCC下编译通过,大家可以运行下看什么效果,在VC下请加入这条语句,屏蔽4786警告 #pragma warning (disable:4786) )


#include 


#include 


#include 


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;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)


{



Cout<first<<” ”<second<<end;


}


}


第二种:用insert函数插入value\_type数据,下面举例说明


#include 


#include 


#include 


Using namespace std;


Int main()


{



Map<int, string> mapStudent;

mapStudent.insert(map<int, string>::value_type (1, “student_one”));

mapStudent.insert(map<int, string>::value_type (2, “student_two”));

mapStudent.insert(map<int, string>::value_type (3, “student_three”));

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)


{



Cout<first<<” ”<second<<end;


}


}


第三种:用数组方式插入数据,下面举例说明


#include 


#include 


#include 


Using namespace std;


Int main()


{



Map<int, string> mapStudent;

mapStudent[1] = “student_one”;

mapStudent[2] = “student_two”;

mapStudent[3] = “student_three”;

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)


{



Cout<first<<” ”<second<<end;


}


}


以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值,用程序说明


mapStudent.insert(map<int, string>::value\_type (1, “student\_one”));


mapStudent.insert(map<int, string>::value\_type (1, “student\_two”));


上面这两条语句执行后,map中1这个关键字对应的值是“student\_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下


Pair<map<int, string>::iterator, bool> Insert\_Pair;


Insert\_Pair = mapStudent.insert(map<int, string>::value\_type (1, “student\_one”));


我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert\_Pair.second应该是true的,否则为false。


下面给出完成代码,演示插入成功与否问题


#include 


#include 


#include 


Using namespace std;


Int main()


{



Map<int, string> mapStudent;


Pair<map<int, string>::iterator, bool> Insert\_Pair;



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

If(Insert_Pair.second == true)

{

      Cout<<”Insert Successfully”<<endl;

}

Else

{

      Cout<<”Insert Failure”<<endl;

}

Insert_Pair = mapStudent.insert(pair<int, string>(1, “student_two”));

If(Insert_Pair.second == true)

{

      Cout<<”Insert Successfully”<<endl;

}

Else

{

      Cout<<”Insert Failure”<<endl;

}

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)


{



Cout<first<<” ”<second<<end;


}


}


大家可以用如下程序,看下用数组插入在数据覆盖上的效果


#include 


#include 


#include 


Using namespace std;


Int main()


{



Map<int, string> mapStudent;

mapStudent[1] = “student_one”;

mapStudent[1] = “student_two”;

mapStudent[2] = “student_three”;

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)


{



Cout<first<<” ”<second<<end;


}


}


3. ```
  map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

Int nSize = mapStudent.size();

数据的遍历



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


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


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


#include 


#include 


#include 


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<first<<” ”<second<<end;


}


}


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


#include 


#include 


#include 


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

#include

#include

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

#include

#include

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;
}

}

数据的清空与判空



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


7. ```
  数据的删除

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

#include

#include

#include

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”));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值