vector、 unique 、erase
先放一个题:2017百度春招笔试:
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32M,其他语言64M
输入描述:
首先输入一个正整数N(N <= 50),接下来输入N个数表示每顶帽子的价格(价格均是正整数,且小于等于1000)
输出描述:
如果存在第三便宜的帽子,请输出这个价格是多少,否则输出-1
输入例子1:
10 10 10 10 10 20 20 30 30 40 40
输出例子1:
30
我的解法:
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 6 bool comp(int a, int b) 7 { 8 return a<b; 9 } 10 11 int main() 12 { 13 int N,x; 14 vector <int> a; 15 while(cin>>N) 16 { 17 for(int i=0;i<N;i++) 18 { 19 cin>>x; 20 a.push_back(x); 21 } 22 sort(a.begin(),a.end(),comp); 23 int index = 0; 24 for(int i = 1; i < a.size(); i++) 25 { 26 if(a[index] != a[i]) 27 a[++index] = a[i]; 28 } 29 if(index>=2) 30 cout<<a[2]<<endl; 31 else cout<<-1<<endl; 32 } 33 return 0; 34 }
动态数组,第一反应是vector,然后去重、输出。
关于vector的部分知识如下:
一、引入
引入:略
vector收录在STL里,是一种特殊的数据结构。它的中文名字叫做“动态数组”或者“不定长数组”,有时也被翻译成“容器”。
说白了,vector就是一个功能强大的数组。下面让我们来体验它强大的功能吧!
二、vector的头文件
vector收录在std库里,所以调用vector需要
#include<vector>
using namespace std;
这两个头文件。
三、vector的声明与构造函数
既然是“动态数组”,vector是一个什么数组呢,int?double?或者结构体数组?
我们可以这样声明一个vector:
vector <数据类型> 动态数组名;
比如:
vector <int> i;//一个int的动态数组
vector <char> c;//一个char的动态数组
vector <node> n;//一个node的动态数组(node是结构体名)
如果你想赋初值,你可以:
vector <int> M(a,b);//在M里装a个b
vector <int> N(a); //在N里装a个0
当然你也可以:
vector <int> A;
vector <int> B(A);//一个和A一模一样的动态数组
vector <int> C(B.begin()+l,B.end()-r);//继承B动态数组下标[l,B.end()-r)的值,注意,下标从0开始,begin(),end(),size()三个函数见下文
四、vector的析构函数
很简单,你可以vector <A> B;//A是某种数据结构,B是动态数组名
如果你想析构它,只需调用B.~vector<A>(); 即可。
也就是说,vector的析构函数是:动态数组名.~vector<该数组的数据结构>();
五、vector的基本操作
以vector <int> v为例:
① v[i]或v.at(i)//返回v[i]的值
② v.size();//返回v数组元素总个数
③ v.front();//返回v数组第一个元素的值
④ v.back();//返回v数组最后一个元素的值
⑤ v.clear();//清空v数组
⑥ v.begin();//返回v数组第一个数的地址
⑦ v.end();//返回v数组最后一个数之后的地址
⑧ v.empty();//判断v数组是否为空,是空则返回1(true),非空(有元素)则返回0(false)
⑨ v.swap(v1);//v1是另一个动态数组,将v和v1元素互换
⑩ swap(v,v1);//同⑨
注意:再次重申,vector的下标是从0开始的!
注意:除v[i]外,其余都是vector的自带函数,因此必须添上括号!
五、vector的插入
std库提供了好几种插入,这里讲最为常用的三种。
① v.push_back(a);//在v数组的尾部插入数a
比如:
有一个动态数组x:2017 2333
调用x.push_back(666);
则x:2017 2333 666
② v.insert(v.begin()+k,a);//在下标k的前面插入数a,k之后的数依次后退一位
//记住,下标是从0开始的!
比如:
动态数组x:1 2 3 4 5 6
调用x.insert(x.begin()+2,100);
则x:1 2 100 3 4 5 6
③ x.insert(x.begin()+k,p,a);//在下标k前面插入p个a
六、vector的删除
也有三种,
① v.pop_back()//删除最后一个元素
② v.erase(v.begin()+k);//删除下标为k的数,返回下一个位置的下标
③ v.erase(v.begin()+l,v.end()-r);//删除下标[l,v.end()-r)的元素
七、vector的内存机制
v.capacity();//返回v数组的长度,就相当于int v[20000];的20000
v.resize(k);//将v数组的长度设为k
当动态数组内的元素比动态数组长度多一时,动态数组长度翻倍!
也就是说:if(v.size()-1==v.capacity()) v.resize(v.capacity()*2);
内存详细分析请看:
原文链接:https://blog.csdn.net/c20182030/article/details/69667965
八、关于vector的去重(unique函数):
unique是 c++标准模板库STL中十分实用的函数之一,使用此函数需要#include <algorithm>头文件
该函数的作用是“去除”容器或者数组中相邻元素的重复出现的元素
(1) 这里的去除并非真正意义的erase,而是将重复的元素放到容器的末尾,返回值是去重之后的尾地址。
(2) unique针对的是相邻元素,所以对于顺序顺序错乱的数组成员,或者容器成员,需要先进行排序,可以调用sort()函数
示例:
文章开头一道题的去重也可以替换为:
unique(a.begin() , a.end()); //“伪”去重,返回值为去重后的尾地址
a.erase(unique(a.begin() , a.end()), a.end());//删去尾部
int index = a.size();//去重后的长度。
九、erase函数原型:
iterator erase(iterator position); //表示删除某一固定位置的元素 iterator erase(iterator first, iterator last); //删除从某个位置至另外一个 位置之间的元素