C++标准模板库(STL)学习记录 Part 1

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的常见用法详解

PATA-10663 Set Similarity

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的常见用法解析

PATA-1060 Are They Equal( S )

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的常用用法详解

PATA-1100 Mars Numbers

PATA-1054 The Dominant Color

PATA-1071 Speech Patterns

PATA-1022 Digital Library

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) 字符串和字符串的映射也有可能会用到

           











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪突猛进!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值