复试上机指南-C++STL(一)

前言

最近在准备复试,博主的复试是C/C++,考虑到C++自带的STL操作的方便性,所以选择了用C++作为机试的语言,预计会做成一个系列,内容包括但不限于:

  1. STL:set、map、序列容器(vector、deque、list、array)、string类、容器适配器(stack、queue、priority_queue)
  2. 常用的数据结构:链表、数组、栈、队列、树、图等常用的数据结构,部分会在前面的STL中涉及,就不在这重复了。
  3. 常用算法:一是#incldue中包含的常用算法;二是关于贪心、动态规划等等。
  4. 排序和搜索:会写一些比较常见或者重要的排序冒泡、选择、快排,线性搜索、二分搜索。因为排序在算法中直接使用sort()即可,所以不会涉及太多,应对复试应该没问题。

本系列会按照是什么、为什么、常用的操作这三块来行文,希望大家看完可以提出宝贵的意见。

关于本文

第一篇主要介绍的是STL中的set、map、序列容器。

1 set

1.1 是什么

从现在开始我们将介绍set (集合)的使用。集合是一个简单直观的数学概念,即具有共同特征的事物的集合。除了没有单独的键,set 容器和 map 容器很相似。定义 set 的模板有 4 种,其中两种默认使用 less 来对元素排序,另外两种使用哈希值来保存元素。有序 set 的模板定义在 set 头文件中。既然是为了实战准备那么我就只介绍平时用的比较多的一种。

1.2 为什么

在机试中常用的是set这种,容器保存 T 类型的对象,而且保存的对象是唯一的,其中保存的元素是有序的,标粗的字体就是使用它的理由,在去除字符串、整数中重复的元素时,可以采取直接插入到set里面,在插入的过程中就会自动去掉重复的元素,并且输出的原有元素是按照从小到大拍好的(字符串按照asc||码表排序的)。

1.3 常用的操作

1.3.1 初始化

在使用时需要加上头文件#include//注意,STL头文件没有扩展名.h,代码示例如下:

#include   
 #include  
using namespace std;
int main()
{
    sets;
    return 0;
}

可对int进行修改,charstring都可以,在初始化结束后就可以利用s进行操作了。

1.3.2 插入、遍历等常用操作

插入
 #include 
 #include 

 using namespace std;
 
 int main()
 {
     int a[] = {1,2,3};
     set s;
     set::iterator iter;
     s.insert(a,a+3);
     for(iter = s.begin() ; iter != s.end() ; ++iter)
     {
         cout<<*iter<<" ";
     }
     cout<

上面这段程序中set::iterator iter;其中iterator是迭代器,用来在插入、遍历等操作中定位集合中元素的位置;在插入时可以是s.inset(1)代表将1插入到set中,而s.insert(a,a+3)是将数组a中的0-2的元素段插入到set中,我们平时在使用时,整数数组也好,字符数组也好或者是字符串,我们不会在一开始就赋好初值,往往都是根据题意自行输入,所以我们需要循环来不断地进行判断进行输入,例如:

while(i!=-1){
	cin>>i;
	s.insert(i);
}
遍历

在输出时,我们也会有固定的格式,比如上文中的:

 for(iter = s.begin() ; iter != s.end() ; iter++)
     {
         cout<<*iter<<" ";
     }

其中s.begin()返回set中的第一个元素;s.end()返回set中最后一个元素,用来判断循环是否结束;在输出时采用*iter类似于指针变量。

常用操作

下面介绍结几个常用的函数:

clear():删除容器中的所有元素
empty():判断容器是否为空
max_size():返回容器中可能包含的最大元素个数
size():返回当前容器中的元素的个数

使用的方法都是s.size()、s.max_size()、s.empty()
重点讲解以下几个erase()//删除函数find()//查找函数equal_range()//返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。最后一个还未遇到过。

set numbers {2, 4, 6, 8, 10, 12, 14};
n = numbers.erase(12);//删除12
n = numbers.erase(13);
numbers.clear();
set::iterator iter;
numbers.erase(iter)//删除定位器iterator指向的值。
numbers.erase(first,second)//删除定位器first和second之间的值。
set numbers {2, 4, 6, 8, 10, 12, 14};
numbers.find(2)//会返回2所在的位置,若没有找到则会返回end()。

以上便是关于set常用的一些代码了,想要掌握的话还是需要实操,后面我会陆续贴出一些题目,供大家练习。

2 map

2.1 是什么

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

2.2 为什么

map会自动建立key-value对应,key和value可以是任意的你想要的类型,可以根据key值进行快速的查找,且查找速度相当快,比如有1000个记录,最多查找10次,1000000记录,最多查找20次;快速插入、快速删除、根据key的值修改value的值、遍历所有记录。
所以掌握好map对我们在以后的做题中会节省很多时间,带来方便的操作。

2.3 常用的操作

2.3.1 初始化

使用map得包含map类所在的头文件#include ,map对象是模板类,需要关键字和存储对象两个模板参数:map m;这样就定义了一个用int作为索引,并拥有相关联的指向string的指针。

2.3.2 插入、遍历等常用操作

插入

下面介绍2种插入的方式:

  1. insert()函数插入
#include   
#include   
#include    
using namespace std;   
int main()  
{   
    map mapStudent;  
    mapStudent.insert(pair(1, "student_one"));  
    mapStudent.insert(pair(2, "student_two"));  
    mapStudent.insert(pair(3, "student_three"));  
    map::iterator iter;  
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
    	 cout<first<<' '<second<

2.用数组插入

#include   
#include   
#include   
using namespace std;  
int main()   
{  
    map mapStudent;  
    mapStudent[1] = "student_one";  
    mapStudent[2] = "student_two";  
    mapStudent[3] = "student_three";  
    map::iterator iter;  
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
        cout<first<<' '<second<

同set类似,在定义了mapmap mapStudent;之后,调用insert()函数进行插入,再插入的时候我们观察到mapStudent.insert(pair(1, "student_one"));是以1,“student_one”这样的键值对进行插入的。这两种插入的方法不同的地方在于,insert()在插入时,如果键值已经存在了就不能在继续插入了,但是数组却可以继续插入,键值对应的新的value可以覆盖之前的value。

遍历
  1. 利用前向迭代器进行遍历,也就是iter=mapStudent.begin();iter!=mapStudent.end();iter++。在遍历时,同样map::iterator iter;写好迭代器,for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)循环从第一个开始,到最后一个结束,在输出时略有不同,cout<first<<' '<second<类似于指针分别输出iter指向的first也就是key,second也就是value。
  2. 利用反向迭代器,for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++),rbegin()、rend()。
  3. 利用数组进行输出for(int nindex = 1; nindex <= nSize; nindex++) cout<
大小

可以用size()函数,Int nSize = mapStudent.size();

查找获取关键字

用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator。

map mapStudent;  
mapStudent.insert(pair(1, "student_one"));  
mapStudent.insert(pair(2, "student_two"));  
mapStudent.insert(pair(3, "student_three"));  
map::iterator iter;  
iter = mapStudent.find(1);  
if(iter != mapStudent.end())  
       cout<<"Find, the value is "<second<
删除元素

移除某个map中某个条目用erase()
该成员方法的定义如下:

iterator erase(iterator it);//通过迭代器对象删除
iterator erase(iterator first,iterator last)//删除一个范围类似set
size_type erase(const Key&key);//通过关键字删除
clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());

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

//如果要删除1,用迭代器删除  
  map::iterator iter;  
  iter = mapStudent.find(1);  
  mapStudent.erase(iter);  
  //如果要删除1,用关键字删除  
  int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0  
  //用迭代器,成片的删除  
  //一下代码把整个map清空  
  mapStudent.erase( mapStudent.begin(), mapStudent.end() );  
  //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
排序

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

#include   
#include   
#include   
using namespace std;  
//结构体中重载<、==、>
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; //学生信息  
int main()  
{  
    int nSize;   //用学生信息映射分数  
    mapmapStudent;  
    map::iterator iter;  
    Studentinfo studentinfo;  
    studentinfo.niD = 1;  
    studentinfo.strName = "student_one";  
    mapStudent.insert(pair(studentinfo, 90));  
    studentinfo.niD = 2;  
    studentinfo.strName = "student_two";  
    mapStudent.insert(pair(studentinfo, 80));  
    for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)  
        cout<first.niD<<' '<first.strName<<' '<second<

以上便是关于map的一些基本操作了,大家还是需要实操的,后面会贴出来一些代码。这是个大佬。

你可能感兴趣的:(考研复试,C++STL,算法)