C++中vector和map使用详解

来源:互联网 发布:五常知乎 编辑:程序博客网 时间:2024/05/17 22:35


vector:

标准库Vector类型

使用需要的头文件:
#include <vector>
Vector:Vector 是一个类模板。不是一种数据类型。 Vector<int>是一种数据类型。

一、 定义和初始化
Vector<T> v1; //默认构造函数v1为空
Vector<T> v2(v1);//v2是v1的一个副本
Vector<T> v3(n,i);//v3包含n个值为i的元素
Vector<T> v4(n); //v4含有n个值为0的元素
二、 值初始化
1> 如果没有指定元素初始化式,标准库自行提供一个初始化值进行值初始化。
2> 如果保存的式含有构造函数的类类型的元素,标准库使用该类型的构造函数初始化。
3> 如果保存的式没有构造函数的类类型的元素,标准库产生一个带初始值的对象,使用这个对象进行值初始化。
三、Vector对象最重要的几种操作
1. v.push_back(t) 在数组的最后添加一个值为t的数据
2. v.size() 当前使用数据的大小
3. v.empty() 判断vector是否为空
4. v[n] 返回v中位置为n的元素
5. v1=v2 把v1的元素替换为v2元素的副本
6. v1==v2 判断v1与v2是否相等
7. !=、<、<=、>、>= 保持这些操作符惯有含义

vector容器类型
vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。vector对象可以在运行时高效地添加元素,并且vector中元素是连续存储的。
vector的构造

函数原型:
template<typename T>
explicit vector(); // 默认构造函数,vector对象为空
explicit vector(size_type n, const T& v = T()); // 创建有n个元素的vector对象
vector(const vector& x);
vector(const_iterator first, const_iterator last);
注:vector容器内存放的所有对象都是经过初始化的。如果没有指定存储对象的初始值,那么对于内置类型将用0初始化,对于类类型将调用其默认构造函数进行初始化(如果有其它构造函数而没有默认构造函数,那么此时

必须提供元素初始值才能放入容器中)。

举例:
vector<string> v1; // 创建空容器,其对象类型为string类
vector<string> v2(10); // 创建有10个具有初始值(即空串)的string类对象的容器
vector<string> v3(5, "hello"); // 创建有5个值为“hello”的string类对象的容器
vector<string> v4(v3.begin(), v3.end()); // v4是与v3相同的容器(完全复制)

vector的操作(下面的函数都是成员函数)

bool empty() const; // 如果为容器为空,返回true;否则返回false
size_type max_size() const; // 返回容器能容纳的最大元素个数
size_type size() const; // 返回容器中元素个数
size_type capacity() const; // 容器能够存储的元素个数,有:capacity() >= size()
void reserve(size_type n); // 确保capacity() >= n
void resize(size_type n, T x = T()); // 确保返回后,有:size() == n;如果之前size()<n,那么用元素x的值补全。

reference front(); // 返回容器中第一个元素的引用(容器必须非空)
const_reference front() const;
reference back(); // 返回容器中最后一个元素的引用(容器必须非空)
const_reference back() const;

reference operator[](size_type pos); // 返回下标为pos的元素的引用(下标从0开始;如果下标不正确,则属于未定义行为。
const_reference operator[](size_type pos) const;
reference at(size_type pos); // 返回下标为pos的元素的引用;如果下标不正确,则抛出异常out_of_range
const_reference at(size_type pos) const;

void push_back(const T& x); // 向容器末尾添加一个元素
void pop_back(); // 弹出容器中最后一个元素(容器必须非空)

// 注:下面的插入和删除操作将发生元素的移动(为了保持连续存储的性质),所以之前的迭代器可能失效
iterator insert(iterator it, const T& x = T()); // 在插入点元素之前插入元素(或者说在插入点插入元素)
void insert(iterator it, size_type n, const T& x); // 注意迭代器可能不再有效(可能重新分配空间)
void insert(iterator it, const_iterator first, const_iterator last);

iterator erase(iterator it); // 删除指定元素,并返回删除元素后一个元素的位置(如果无元素,返回end())
iterator erase(iterator first, iterator last); // 注意:删除元素后,删除点之后的元素对应的迭代器不再有效。

void clear() const; // 清空容器,相当于调用erase( begin(), end())

void assign(size_type n, const T& x = T()); // 赋值,用指定元素序列替换容器内所有元素
void assign(const_iterator first, const_iterator last);

const_iterator begin() const; // 迭代序列
iterator begin();
const_iterator end() const;
iterator end();

const_reverse_iterator rbegin() const;
reverse_iterator rbegin();
const_reverse_iterator rend() const;
reverse_iterator rend();

vector对象的比较(非成员函数)

针对vector对象的比较有六个比较运算符:operator==、operator!=、operator<、operator<=、operator>、operator>=。

其中,对于operator==和operator!=,如果vector对象拥有相同的元素个数,并且对应位置的元素全部相等,则两个vector对象相等;否则不等。
对于operator<、operator<=、operator>、operator>=,采用字典排序策略比较。
注:其实只需要实现operator==和operator!=就可以了,其它可以根据这两个实现。因为,operator!= (lhs, rhs) 就是 !(lhs == rhs),operator<=(lhs, rhs) 就是 !(rhs < lhs),operator>(lhs, rhs) 就是 (rhs < lhs),

operator>=(lhs, rhs) 就是 !(lhs, rhs)。

vector类的迭代器
vector类的迭代器除了支持通用的前缀自增运算符外,还支持算术运算:it + n、it - n、it2 - it1。注意it2 - it1返回值为difference_type(signed类型)。

注意,任何改变容器大小的操作都可能造成以前的迭代器失效。

应用示例

#include <iostream>
#include <cassert>
#include <vector>
using namespace std;
int main()
{
vector<string> v(5, "hello");
vector<string> v2(v.begin(), v.end());

assert(v == v2);

cout<<"> Before operation"<<endl;
for(vector<string>::const_iterator it = v.begin(); it < v.end(); ++it)
cout<<*it<<endl;

v.insert(v.begin() + 3, 4, "hello, world");
cout<<"> After insert"<<endl;
for(vector<string>::size_type i = 0; i < v.size(); ++i)
cout<<v[i]<<endl;

vector<string>::iterator it = v.erase(v.begin() + 3, v.begin() + 6);
assert(*it == "hello, world");
cout<<"> After erase"<<endl;
for(vector<string>::size_type i = 0; i != v.size(); ++i)
cout<<v[i]<<endl;

assert(v.begin() + v.size() == v.end());
assert(v.end() - v.size() == v.begin());
assert(v.begin() - v.end() == -vector<string>::difference_type(v.size()));

return 0;
}

程序说明:上面程序中用了三个循环输出容器中的元素,每个循环的遍历方式是不一样的。特别需要说明的是,第二个循环在条件判断中使用了size() 函数,而不是在循环之前先保存在变量中再使用。之所以这样做,有两个

原因:其一,如果将来在修改程序时,在循环中修改了容器元素个数,这个循环仍然能很好地工作,而如果先保存size()函数值就不正确了;其二,由于这些小函数(其实现只需要一条返回语句)基本上都被声明为inline,所

以不需要考虑效率问题。
---------------------------------
c++编程语言中有一种叫做Vector的应用方法,它的作用在实际编程中是非常重要的。在这里我们将会为大家详细介绍一下C++ Vector的相关应用技巧及基本内容,希望能给大家带来一些帮助。
(1)vector< 类型 > 标识符 ;
(2)vector< 类型 > 标识符(最大容量) ;
(3)vector< 类型 > 标识符(最大容量,初始所有值);
(4) int i[4] = {12,3,4,5};
vector< 类型 > vi(i , i+2); //得到i索引值为3以后的值 ;
(5)vector< vector<int> > //vi 定义2维的容器;记得一定要有空格,不然会报错
vector< int > line
// 在使用的时候一定要首先将vi个行进行初始化;
for(int i = 0 ; i < 10 ; i ++)
{
vector.push_back(line);
}
/// 个人认为使用vector定义二维数组很好,
因为是长度可以不预先确定。很好。
(6)C++ Vector排序
vector< int > vi ;
vi.push_back(1);
vi.push_back(3);
vi.push_back(0);
sort(vi.begin() , vi.end()); /// /小到大
reverse(vi.begin(),vi.end()) /// 从大道小
(7)顺序访问
vector < int > vi ;
for( int i = 0 ; i < 10 ; i ++)
{
vector.push_back(i);
}
for(int i = 0 ; i < 10 ; i ++) /// 第一种调用方法
{
cout <<vector[i] <<" " ;
}
for(vector<int>::iterator it = vi.begin() ;
it !=vi.end() ; it++) ///第二种调用方法
{
cout << *it << " " ;
}
(8)寻找
vector < int > vi ;
for( int i = 0 ; i < 10 ; i ++)
{
vector.push_back(i);
}
vector < int >::interator it = find(vi.begin() , vi.end,3) ;
cout << *it << endl ; ///返回容器内找到值的位置。
(9)使用数组对C++ Vector进行初始化
int i[10] ={1,2,3,4,5,6,7,78,8} ;
///第一种
vector<int> vi(i+1,i+3); ///从第2个元素到第三个元素
for(vector <int>::interator it = vi.begin() ;
it != vi.end() ; it++)
{
cout << *it <<" " ;
}
(10) 结构体类型
struct temp
{
public :
string str ;
public :
int id ;
}tmp
int main()
{
vector <temp> t ;
temp w1 ;
w1.str = "Hellowor" ;
w1.id = 1 ;
t.push_back(t1);
cout << w1.str << "," <<w1.id <<endl ;
return 0 ;

}

转:https://software.intel.com/zh-cn/blogs/2011/08/10/c-vector

======================================================================

     map:

   来源:(http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html

    Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!
1. map最基本的构造函数;
   map<string , int >mapstring;         map<int ,string >mapint;
   map<sring, char>mapstring;         map< char ,string>mapchar;
   map<char ,int>mapchar;            map<int ,char >mapint;

2. map添加数据;

   map<int ,string> maplive;  
   1.maplive.insert(pair<int,string>(102,"aclive"));
   2.maplive.insert(map<int,string>::value_type(321,"hai"));
   3, maplive[112]="April";//map中最简单的插入添加!慎用,如果不存在,会把新元素插入
3,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;
4,map中元素的删除:
   如果删除112;
   map<int ,string >::iterator l_it;;
   l_it=maplive.find(112);
   if(l_it==maplive.end())
        cout<<"we do not find 112"<<endl;
   else  maplive.erase(l_it);  //delete 112;
5,map中 swap的用法:
  Map中的swap不是一个容器中的元素交换,而是两个容器交换;
  For example:
  #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 map
   m1.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 swap
   swap( 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;
}

6.map的sort问题:
  Map中的元素是自动按key升序排序,所以不能对map用sort函数:
  For example:
  #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;
  
}
  The original map m1 is:
  1 20
  2 50
  3 60
  4 40
  6 40
  7 30
  请按任意键继续. . .

7,   map的基本操作函数:
      C++ Maps是一种关联式容器,包含“关键字/值”对
      begin()          返回指向map头部的迭代器
      clear()         删除所有元素
      count()          返回指定元素出现的次数
      empty()          如果map为空则返回true
      end()            返回指向map末尾的迭代器
      equal_range()    返回特殊条目的迭代器对
      erase()          删除一个元素
      find()           查找一个元素
      get_allocator()  返回map的配置器
      insert()         插入元素
      key_comp()       返回比较元素key的函数
      lower_bound()    返回键值>=给定元素的第一个位置
      max_size()       返回可以容纳的最大元素个数
      rbegin()         返回一个指向map尾部的逆向迭代器
      rend()           返回一个指向map头部的逆向迭代器
      size()           返回map中元素的个数
      swap()            交换两个map
      upper_bound()     返回键值>给定元素的第一个位置
      value_comp()      返回比较元素value的函数

 8、iterator是否为空的判断

对于容器而言,是判断是否为end();对于sring而言,是判断是否是string::npos,但是如果是针对string的话,就不是"iterator",而是一般的整型值而已

9、iterator的初始化----用end()

list<char*>  list;

list<char*>::iterator it=slist.end();

---------------------------------------------------------------

map详解:

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;

2.       数据的插入

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

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

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

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

{

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

}

}

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

#include <map>

#include <string>

#include <iostream>

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

}

}

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

#include <map>

#include <string>

#include <iostream>

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<<iter->first<<”   ”<<iter->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 <map>

#include <string>

#include <iostream>

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

}

}

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

#include <map>

#include <string>

#include <iostream>

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

}

}

3.       map的大小

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

Int nSize = mapStudent.size();

4.       数据的遍历

这里也提供三种方法,对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的特性,删除区间是一个前闭后开的集合

 

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

}

8.       其他一些函数用法

这里有swap,key_comp,value_comp,get_allocator等函数,感觉到这些函数在编程用的不是很多,略过不表,有兴趣的话可以自个研究

9.       排序

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题

第一种:小于号重载,程序举例

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

       Int      nID;

       String   strName;

}StudentInfo, *PStudentInfo;  //学生信息

 

Int main()

{

    int nSize;

       //用学生信息映射分数

       map<StudentInfo, int>mapStudent;

    map<StudentInfo, int>::iterator iter;

       StudentInfo studentInfo;

       studentInfo.nID = 1;

       studentInfo.strName = “student_one”;

       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

       studentInfo.nID = 2;

       studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

 

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

    cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;

 

}

以上程序是无法编译通过的,只要重载小于号,就OK了,如下:

Typedef struct tagStudentInfo

{

       Int      nID;

       String   strName;

       Bool operator < (tagStudentInfo const& _A) const

       {

              //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序

              If(nID < _A.nID)  return true;

              If(nID == _A.nID) return strName.compare(_A.strName) < 0;

              Return false;

       }

}StudentInfo, *PStudentInfo;  //学生信息

第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

       Int      nID;

       String   strName;

}StudentInfo, *PStudentInfo;  //学生信息

 

Classs sort

{

       Public:

       Bool operator() (StudentInfo const &_A, StudentInfo const &_B) const

       {

              If(_A.nID < _B.nID) return true;

              If(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0;

              Return false;

       }

};

 

Int main()

{

       //用学生信息映射分数

       Map<StudentInfo, int, sort>mapStudent;

       StudentInfo studentInfo;

       studentInfo.nID = 1;

       studentInfo.strName = “student_one”;

       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

       studentInfo.nID = 2;

       studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

}

10.   另外

由于STL是一个统一的整体,map的很多用法都和STL中其它的东西结合在一起,比如在排序上,这里默认用的是小于号,即less<>,如果要从大到小排序呢,这里涉及到的东西很多,在此无法一一加以说明。

还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL  Algorithm也可以完成该功能,建议用map自带函数,效率高一些。

下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方很费内存了吧,不说了……



2 0