C++的STL介绍

一、常见的STL容器介绍

1、vector

(1)常用操作:赋值、删除、访问元素、获取元素个数

1)顺序赋值:

使用v.push_back(value),也可以使用v[i]=value赋值,但要注意数据越界问题;


2)删除(注意:删除后依然保持顺序连通性,并不是被删下标处变为空):

①删除任意指定位置:v.erase(iter)(注:返回值所指数据为原数列的下一个数值),遍历时删除元素要注意迭代器失效问题;

在遍历中使用erase()举例:

	for(vector<int>::iterator iter=v.begin();iter!=v.end();)
	{
		if(*iter==5)
		{
			iter=v.erase(iter);	//删除后该迭代器及其后面迭代器都已失效,必须重新赋值
		}
		else
		{
			cout<<*iter<<' ';
			iter++;
		}
	}

注:vector<int>::iterator iter迭代器定义方式表明,迭代器前要有容器类型修饰符,以表明属于哪个容器的迭代器;

②删除末尾数值:v.pop_back();


3)访问

如101节所示,可以使用v[i]直接访问,只要自己注意访问越界就可;也可以使用v.at(i),该方式下编译器会自动检查越界;


4)获取元素个数

v.size(); //对各容器通用


(2)vector的其他作用

1)模拟循环链表

方法:使用迭代器实现,例如:

if(iter==v.end())

iter=v.begin();



2、stack

(1)常用操作:定义、出栈入栈、读取栈顶元素、获取元素个数、判断栈是否为空

1)定义:

stack<int> s 类似;


2)入栈出栈:

s.push(x)、s.pop();

注意:pop仅仅是出栈,不会返回值


3)读取栈顶数据

s.top();//返回值为栈顶数据


4)读取栈中实际数据个数

s.size();


5)判断栈是否为空

s.empty();


3、queue

(1)常用操作:定义、入队出队、访问队首队尾、获取队列中元素个数、判断对内是否为空

1)定义

queue<int> q 类似定义;


2)入队出队

q.push(x); //队首入队

q.pop(); //队尾出队,仅仅是出队,无返回值 


3)访问队首队尾

q.front(); //访问队首元素

q.back(); //访问队尾元素


4)获取队列中元素个数

q.size();


5)判断队列是否为空

q.empty();



4、string

(1)定义并初始化、string对象操作(判断空、获取字符个数(不包括'\0')、字符串连接、字符串比较)

1)string对象的定义和初始化以及读写

string s1; 默认构造函数,s1为空串

string s2(s1); 将s2初始化为s1的一个副本

string s3("valuee"); 将s3初始化一个字符串面值副本

string s4(n,'c'); 将s4 初始化为字符'c'的n个副本

cin>>s5; 读取有效字符到遇到空格结束

getline(cin,s6); 读取一行字符串,空格可读入,直到‘\n’结束(换行结束),

getline(cin,s7,'a'); 一个直到‘a’结束,其中任何字符(包括'\n')都能够读入



2)string对象操作

①判断是否为空:

s.empty() 判断是否为空,bool型

②获取字符串中字符个数:

s.size() 或 s.length() 返回字符的个数(注意:不包括结尾'\0')


③字符串连接:

直接用加法,如s1+s2 连接,看下面例子:

可用此方法给字符串后面添加字符如:s=s+'a'; 

a: string s2=s1+", "; //对,把一个string对象和一个字符面值连接起来是允许的

b: string s4="hello "+", "; //错,不能将两个字符串面值相加(两个字符串都是常量,而相加结果应该先赋值给前者,前者不可修改,再赋给等号左边的,故该用法非法)

c: string s5=s1+", "+"world"; //对,前面两个相加相当于一个string对象;

d: string s6="hello" + ", " + s2; //错(原因同s4,第一个不能是常量)

(注:字符串尾部追加还可用s.append("abc")函数添加)


④字符串比较:

直接用算术比较符号(=、>=、<=、>、<、!=),例如:

s1==s2 相等,还用、有!=,<,<=,>,>= 字符串比较,返回true或false;

两个字符串短的与长的前面匹配,短的小于长的;


(2)string对象常用函数

1)插入函数:

包括迭代器操作和下标操作,下标操作更灵活;

s.insert( it , p );把字符串p插入到it的位置

s.insert(p,n,t);迭代器p元素之前插入n个t的副本

s.insert(p,b,e);迭代器p元素之前插入迭代器b到e之间的所有元素

s.insert(p,s2,poe2,len);在下标p之前插入s2下标从poe2开始长度为len的元素

s.insert(pos,cp,len);下标pos之前插入cp数组的前len个元素。


2)替换函数

s.assign(b,e);用迭代器b到e范围内的元素替换s

s.assign(n,t);用n个t的副本替换s

a.assign(s1,pos2,len);从s1的下标pos2开始连续替换len个。

s.replace ( 3 , 3 , " good " ) ;从第三个起连续三个替换为good

3)截取函数

s.substr(i,len); 截取s串中从i开始截取长度为len的子串 

s.substr(i);截取从第i个元素开始到最后一个元素的子串


3)删除函数
s.erase( 3 )||s.erase ( 0 , 4 ) ; 删除第四个元素或第一到第五个元素


4)其他函数

s.find ( " cat " ) ;正向查找第一个出现的字符串”cat“,返回cat首字符下标值,查不到返回string::npos或者 -1(string::npos==-1)

——举例:string str="123good5good78\0";st=str.find("good"); 结果:st=3;

注意,此函数也可查找字符;

s.rfind ( " cat " ) ; 反向查找第一个出现的字符串”cat“,返回cat首字符下标值,查不到返回string::npos或者 -1(string::npos==-1)

——举例string str="123good5good78\0";st=str.rfind("good"); 结果:st=8;

注意,此函数也可查找字符;


s.find_first_of(str); 函数是正向查找s中查找与str字符串中任何一个字符匹配的字符,如有,则返回第一个找到的字符下标,否则返回string::npos;

例如:string str="12345678\0";st=str.find_first_of("458god"); 结果:st=3;


s.find_last_of(str);函数是正向查找s中查找与str字符串中任何一个字符匹配的字符,如有,则返回最后一个找到的字符索引,否则返回string::npos;

例如:string str="12345678\0";st=str.find_last_of("458god"); 结果:st=7;


此外,find_last_of()的参数还可以是字符,例如filePath.find_last_of('\\')可以用来获取路径最后的文件名的首字符下标(注意必须使用'\\',因为一个反斜杠被认为是转义字符标志);


s.find_first_not_of(str);在字符串s中查找第一个与str中的任一字符都不匹配的字符,返回它的下标位置。搜索从index正向开始。如果没找到就返回string::nops;


find_last_not_of(str);在字符串s中查找最后一个与str中的任一字符都不匹配的字符,返回它的位置。搜索从index逆向开始。如果没找到就返回string::nops

s.append(args);将args接到s的后面;

s.compare ( " good " ) ;s与”good“比较相等返回0,比"good"大返回1,小则返回-1;


5)自己实现字符串和数值互相转化

①流对象:

//c++方法:将数值转换为string  
string convert_to_string(double x)  
{  
    ostringstream o;  
    if(o << x)  
        return o.str();
}  
//c++方法,将string转化为数值  
double convert_from_string(const string &s)  
{  
    istringstream i(s);  
    double x;  
    if(i >> x)  
        return x;  
    return 0.0;  
}  

②使用C++库函数实现(需要引入<string>):

——数值转化为string:

string str=std::to_string(num);   

注意,上述在VS2010中会出错,因为vs2010只实现了部分类型,对于int 、bool等类型需要如下:
std::to_string(static_cast<long long>(3));
std::to_string(static_cast<long long>(true));


——string转化为数值

int num=std::stoi(const string& str, size_t* idx = 0, int base = 10);//结果是十进制

除int外,还有stol、stof、stod等;

形参说明: 

str:表示被转换的字符串;

idx:表示一个size_t*的指针类型,默认为空值或0;

base:表示转换基准,即表示将当前字符串进制,默认是10进制。

举例:

	string testStr="12345";
	int nn=std::stoi(testStr,0,8);
	cout<<nn<<endl;

结果是:5349(十进制)


二、迭代器介绍

1、迭代器的定义:

定义vector<int>容器的迭代器:vector<int>::iterator iter;

定义map<string, pair<string,int>>容器的迭代器:map<string, pair<string,int>>::iterator iter;

……


2、迭代器在遍历中的使用

①遍历中不删除或插入元素:for(vector<int>::iterator iter=v.begin();iter!=v.end();iter++){ }

②遍历中需要删除或插入元素,如下:

	for(vector<int>::iterator iter=v.begin();iter!=v.end();)
	{
		if(*iter==5)
		{
			iter=v.erase(iter);	//删除后该迭代器及其后面迭代器都已失效,必须重新赋值
		}
		else
		{
			cout<<*iter<<' ';
			iter++;
		}
	}

注:vector<int>::iterator iter迭代器定义方式表明,迭代器前要有容器类型修饰符,以表明属于哪个容器的迭代器;


三、常用STL算法介绍

说明:

(1)STL几乎封装了容器常用的一切算法,平时多使用可以减少代码量,节省时间,是否减少复杂度根据情况而定;

(2)使用前需要引入<algorithm>;

1、排序算法sort()和stable_sort()

(1)使用sort()或者stable_sort(),这两个函数是属于algorithm库的,对各个有序容器(不包括map这种无序的)通用;
①sort(v.begin(),v.end());//不稳定排序,默认升序排列
②stable_sort(v.begin(),v.end());//稳定排序,默认升序

(2)若要降序排列还需要增加一个比较函数,例如对于容器vector<pair<string,int>> v容器排序,比较函数如下:
bool cmp(const pair<string, int> &a, const pair<string, int> &b)	//参数类型为容器中元素类型的常量引用形式
{
	return a.second>b.second;	
}

然后,调用sort()或者stable_sort()函数如下:

sort(v.begin(),v.end(),cmp); //表示按照v中pair类型元素的第二个值的降序排序


2、判断容器中是否有某元素算法find()

(1)使用find()函数可以查找一个容器中是否有某元素,有就返回迭代器地址,无则返回xx.end();

例如:vector<int> v;

find(v.begin(),v.end(),10);  //查找v中是否有值为10的元素

应用举例:

vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);

vector<int>::iterator ret;
ret = std::find(vec.begin(), vec.end(), 15);
if(ret == vec.end())
     cout << "not find" << endl;
else
     cout << "finded" << endl;

3、容器元素顺序反转函数

reverse(begin(),end())可以对vector、string进行元素顺序反转:

(1)string反转

string s;

reverse ( s.begin(), s.end () );//对string反向排序;

(2)vector反转

vector<int> v;

reverse ( v.begin(), v.end () );//对vector反向排序;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值