1.vector的常见用法详解
PATA-1039 Course List for Student
PATA-1047 Student List for Course
1.1 vector的定义
vector<typename> name;
如果typename是一个STL容器,定义的时候要记得>>符号之间加上空格,因为一些使用C++11之前标准编译器会把它视为移位操作,导致编译错误。
vector<int> name1;
vector<double> name2;
vector<char> name3;
vector<vector<int> > name4;
二维vector数组,即Arrayname[]中的每一个元素都是一个vector
vector<typename> Arrayname[arraySize];
vector<int> vi[100]
一维长度已经固定为arraySize,另一维才是边长的
1.2 vector容器内元素的访问
(1)通过下标访问 vi[0] vi[1] , 下标是从0到vi.size()-1
(2)通过迭代器访问
迭代器(iterator)可以理解一中类似指针的东西
vector<typename>::iterator it; it是 vector<typename>::iterator型变量
#include <cstdio>
#include <vector>
using namespace std;
int main() {
vector<int> vi;
for(int i=1;i<=5;i++){
vi.push_back(i); //在vi的末尾添加元素i
}
vector<int>::iterator it = vi.begin();
//vi.begin()为取首元素的地址,而it指向这个地址
for(int i=0;i<5;i++){
printf("%d ",*(it+i));
}
return 0;
}
此外,end()函数并不是取vi的尾元素地址,而是取尾元素的下一个地址,作为迭代器末尾标志,不存储任何元素,可以看做是一个左闭右开的区间,这个的begin和end同理,用end函数遍历
for(vector<int>::iterator it = vi.begin();it!=vi.end();it++){
printf("%d ",*it);
}
1.3 vector常用函数实例解析
(1)push_back() 时间复杂度O(1)
push_back(x)在vector后面添加一个元素x,
(2)pop_back() 时间复杂度O(1)
删除vector的尾元素
(3)size() 时间复杂度O(1)
vi.size()获取vi中元素个数,返回的是unsigned类型,不过用%d也没有太大问题,这一点对于所有STL容器都是一样的
(4)clear() 时间复杂度O(N),N为元素个数
vi.clear()用来清空vi中的所有元素
(5)insert() 时间复杂度O(N)
vi.insert(it,x)用来向vi的迭代器it处插入一个元素x
(6)erase() 时间复杂度O(N)
删除单个元素
vi.insert(vi.begin()+2,-1); //将-1插入vi[2]的位置
vi.erase(vi.begin()+2); //再讲插入的元素删除
删除一个区间内的元素
vi.erase(vi.begin()+1,vi.begin()+4); //删除v[1],v[2],v[3]
1.4 vector的常见用途
(1)存储数据
(2)用邻接表存储图
使用vector实现邻接表可以让一些对指针不太熟悉的人有一个比较方便的写法
2. set的常见用法详解
2.1 set的定义
set,集合,是一个内部自动有序且不含重复元素的容器set<typename> name;
set数组的定义和vector相同,set<int> a[100]
2.2 set容器内元素的访问
set只能通过迭代器iterator访问
set<typename>::interator it; 通过*it访问set里的元素,由于除了vector和string之外的STL容器都不支持 *(it+i) 的访问方式,因此只能按如下方法枚举
set<int> st;
st.insert(3);
st.insert(5);
st.insert(2);
st.insert(3);
//注意,不支持it<st.end()的用法
for(set<int>::iterator it=st.begin();it!=st.end();it++){
printf("%d ",*it);
}
输出 2 3 5 ,set内元素自动排序,且去掉了重复元素
2.3 set常用函数实例解析
(1)insert() 时间复杂度O(lonN) , N为set内的元素个数
st.insert(x)可将x插入set容器中,并自动递增排序和去重
(2)find() 时间复杂度O(lonN)
find(value)返回set中对应值为value的迭代器
printf("%d",*(st.find(2)));
(3)erase()
删除单个元素
st.erase(it),it为所需要删除元素的迭代器,可以结合find函数使用,时间复杂度O(1)
st.erase(st.find(2)); //利用find函数找到2,然后用erase删除它
st.erase(value) ,value为所删除的值,时间复杂度O(logN)。
st.erase(2); //删除st集合中值为2的元素
删除一个区间内的所有元素
set<int>::iterator it = st.find(3);
st.erase(it,st.end()); //删除3至set末尾之间的元素
(4)size() 时间复杂度O(1)
st.size() 获得集合st的元素个数
(5)clear() 时间复杂度O(N)
st.clear() 清空st集合中的所有元素
2.3 set的常见用途
set最主要的作用是自动去重并按升序排序,因此碰到需要去重但是却不方便直接开数组的情况,可以用set解决
set中的元素是唯一的,如果需要处理不唯一的情况,则需要使用multiset。另外,C++11标准中还增加了unordered_set,以散列代替set内部的红黑树实现,使其可以用来处理只去重但不排序的需求,速度比set快得多
3. string的常见用法解析
3.1 string的定义
string str = "I_love_u";
3.2 string中内容的访问
(1)通过下标访问,一般来说,可以直接像字符数组那样去访问string,即str[i]
如果要读入和输出整个字符串,则只能通过cin和cout,如果用c_str()将string类型转换为字符数组进行输出
string str;
cin>>str;
cout<<str<<endl;
printf("%s\n",str.c_str());
(2)通过迭代器访问,一般通过方法(1)即可满足访问的要求,但有些函数比如insert和find则要求以迭代器为参数
定义:string::iterator it
for(string::iterator it = str.begin();it!=str.end();it++){
printf("%c",*it);
}
3.3 string常用函数实例解析
(1)operator+= 这是string的加法,可以将两个string直接拼接起来
string str1="abc",str2="xyz",str3;
str3 = str1+str2; //str3="abcxyz"
(2)compare operator 两个string类型可以通过使用== != < <= > >=比较大小,比较规则是字典序
(3)length()/size()
length()返回string的长度,即存放的字符数,时间复杂度为O(1)。size和length基本相同
(4)insert()
string的insert函数有很多种写法,这里给出几个常用的写法,时间复杂度为O(N)
insert(pos,string) ,在pos号位置插入字符串string
string str="abcxyz",str2="opq";
str.insert(3,str2); //输出的是abcopqxyz,是在下标为3的元素前面插入
insert(it,it2,it3),it为原字符串欲插入的位置,it2和it3为待插字符串的首位迭代器,用来表示串 [ it2 , it3 )将被插在it位置上
string str="abcxyz",str2="opq";
str.insert(str.begin()+3,str2.begin(),str2.end());
(5)erase()
删除单个元素,时间复杂度为O(N)
str.erase(it),it为需要删除的元素的迭代器
string str="abcdefg";
str.erase(str.begin()+2); //删除c,
删除一个区间内的所有元素
str.erase(first,last) 参数为迭代器,删除区间为 [ first , last ) ,前闭后开
string str="abcdefg";
str.erase(str.begin()+2,str.end()-1); //删除cdef,输出abg
str.erase(pos,length) ,其中pos为需要开始删除的起始位置,length为删除的字符个数
string str="abcdefg";
str.erase(2,4); //同上,删除cdef,输出abg
(6)clear() 时间复杂度为O(1)
str.clear()
(7)substr() 时间复杂度为O(len)
substr(pos,len) 返回从pos号开始、长度为len的字符串
string str = "Thank you for your smile";
cout<<str.substr(0,5)<<endl; //输出Thank
cout<<str.substr(14,4)<<endl; //输出your
cout<<str.substr(19,5)<<endl; //输出smile
(8)string::npos
string::npos是一个常数,其本身的值为-1,但由于是unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。string::npos用以作为find函数失配时的返回值,下面的例子可以认为string::npos等于-1或4294967295
(9)find()
str.find(str2),当str2是str的子串时,返回其在str中第一次出现的位置;如果str2不是str的子串,那么返回string::npos
str.find(str,pos) , 从str的pos号位开始匹配str2,返回值与上相同
时间复杂度均为O(mn),其中m和n分别为str和str2的长度
string str = "Thank you for your smile.";
string str2 = "you";
string str3 = "me";
if(str.find(str2) != string::npos){
cout<<str.find(str2)<<endl; //输出6
}
if(str.find(str2,7) != string::npos){
cout<<str.find(str2,7)<<endl; //输出14
}
if(str.find(str3) != string::npos){
cout<<str.find(str3)<<endl;
}else{
cout<<"I know there is no position for me."<<endl; //输出此句
}
4. map的常用用法详解
4.1 map(映射)的定义
map<typename1,typename2> mp;
如果是字符串到整型的映射,必须使用string而不能用char数组
map<string , int> mp;
map的键和值也可以是STL容器 map<set<int> , string > mp;
4.2 map容器内元素的访问
(1)通过下标访问,注意,map的键,即typename1是唯一的
map<char,int> mp;
mp['c'] = 20;
mp['c'] = 30; //20会被覆盖,因为键是唯一的
printf("%d\n",mp['c']); //输出30
(2)通过迭代器访问
map<typename1,typename2>::iterator it; 因为map的每一对映射都有两个typename,这决定了必须能通过一个it来同时访问键和值,用->first , it->second
for(map<char,int>::iterator it = mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
4.3 map常用函数实例解析
(1)find()
find(key) 返回键为key的映射的迭代器,时间复杂度O(logN) ,N为map中映射的个数。
map<char,int> mp;
mp['a'] = 1;
mp['b'] = 2;
mp['c'] = 3;
map<char,int>::iterator it = mp.find('b');
printf("%c %d\n",it->first,it->second)
(2)erase()
删除单个元素
mp.erase(it) , it为需要删除的元素的迭代器。时间复杂度为O(1)
map<char,int>::iterator it = mp.find('b');
mp.erase(it);
mp.erase(key) , key为欲删除的映射的键。时间复杂度O(logN),N为map内元素
map<char,int> mp;
mp['a'] = 1;
mp['b'] = 2;
mp['c'] = 3;
mp.erase('b');
删除一个区间内的所有元素
mp.erase(first,last) first,last均为迭代器,删除左闭右开的区间 [ first , last ) 。时间复杂度为 O( last - first )
map<char,int>::iterator it = mp.find('b');
mp.erase(it,mp.end()); //删除it之后的所有映射
(3)size() 用来获得map中映射的对数,时间复杂度为O(1)
(4)clear() 用来清空map中的所有元素,复杂度为O(N)
4.4 map的常见用途
(1) 需要建立字符(或字符串)与整数之间映射的题目,使用map可以减少代码量
(2) 判断大整数或者其他类型数据是否存在的题目,可以把map当bool数组使用
(3) 字符串和字符串的映射也有可能会用到