Standard Template Library,由惠普开发的一系列软件的统称,现在主要用在c++中,内嵌在编译器中,不需要安装。
熟练使用stl才算优秀的c++程序员。
stl从广义上分为3类:
容器和算法通过迭代器进行无缝连接,比传统的函数和类组成的库提供了更好的代码重用机会。
在c++标准中,stl有以下主要的头文件:
,,
,,,,,
graph LR
A[STL]-->B[string]
A-->C[iterator]
C-->D[algorithm]
C-->E[container]
stl的6大组件
stl的重要特点是数据结构和算法的分离。
重复利用已有的实现构造自己的特定类型下的数据结构。
数据结构:研究结点之间的关系。
容器分为2类:
vector,deque,list
。set,multiset,map,multimap
。分为10类。
语言支持相关:
.
io流相关:
诊断功能:
工具:
字符串处理:
容器类的模板:,
迭代器:
算法:
数值操作:
本地化:
所有容器提供值语义value
,而不是引用语义reference
。所以执行添加操作时,要确保容器内的元素有拷贝构造函数,无参构造函数并重载赋值运算符。尤其是有指针成员时。
重点有初始化、遍历、连接、查找和替换、插入、反转和大小写转换。
而且,不用担心越界的问题。
//初始化
#include
using namespace std;
#include "string"
int main()
{
string s1 = "aaa";
string s2("bbb");
string s3 = s1; // copy constructor
string s4(3,'c');
cout<
3种方法:数组,迭代器,at()
。
#include
using namespace std;
#include "string"
int main()
{
string s = "abcdef";
for(int i = 0; i < s.length(); i++)
{
cout<
调试一下可以验证,s.end()
指向s[s.size()]
,也就是最后一个元素之后。
相比于[]
,at()
可以抛出异常。
#include
using namespace std;
#include "string"
int main()
{
string s = "abcdef";
try
{
for(int i = 0; i < s.length() + 3; i++)
{
cout<
初始化时可以实现char*-->string
,通过const char* c_str() cosnt{}
,就能实现string-->char*
。
把string
拷贝到一段内存中,可以用int copy(char *s,int n,int pos=0) const;
,返回值为拷贝数,该函数不保证不越界。
#include
using namespace std;
#include "string"
int main(int argc, char *argv[])
{
string s = "abcdef";
//string-->char*
printf("%s\n",s.c_str());
//string-->buf
char buf[10] = {0};
s.copy(buf,5);
printf("%s\n",buf);
cin.get();
return 0;
}
/*
abcdef
abcde
*/
可以用重载的加号运算符或者string &append();
,第2个参数如下:
const char*
const char *s,int n
const string &s
const string &s,int pos,int n
int n,char c
,添加n个c#include
using namespace std;
#include "string"
int main(int argc, char *argv[])
{
string s1 = "abc";
string s2 = "def";
s1 = s1 + s2;
cout<
string substr(int pos = 0,int n=npos) const;
返回由pos开始的长度n的字符串。
int find(char c, int pos=0) const;
int find(const char*s,int pos=0) const;
int find(const string &s,int pos=0) const;
这3个find()
也有对应的rfind()
,从后往前查找,pos默认参数为string::npos
。
string:npos是个特殊值,说明查找没有匹配
string &replace(int pos,int n,const char*s)
,删除pos开始的n个字符,插入s。
void swap(string &s)
,交换当前字符串与s的值。
#include
using namespace std;
#include "string"
int main(int argc, char *argv[])
{
string s = "aaa When I aaa was aaa.";
int index = 0;
index = s.find("When");
cout<
string &erase(int pos=0, int n=npos);
,删除pos处的n个字符。
iterator erase ( iterator first, iterator last );
string &insert(int pos,const char*s);
string &insert(int pos,const string &s);
string &insert(int pos, int n, int c);
#include
using namespace std;
#include "string"
int main(int argc, char *argv[])
{
string s = "hello world.";
string::iterator it = find(s.begin(),s.end(),'l');
if(it != s.end())
{
s.erase(it);
}
cout<<"s: "<
#include
using namespace std;
#include "string"
#include "algorithm"
int main(int argc, char *argv[])
{
string s = "aaaBBB";
transform(s.begin(), s.end(), s.begin(), toupper);
cout << s << endl;
transform(s.begin(), s.end(), s.begin(), tolower);
cout << s << endl;
cin.get();
return 0;
}
vector容器把元素存进动态数组,尾部添加或删除快,中间添加或删除需要移动后面的元素。vector可以随机存储元素,并支持[]
和at()
。
vector采用模板类实现,即vector
存放自定义类时,由于需要值复制,所以必须提供拷贝构造函数。
v.front()
和v.back()
返回第一个和最后一个元素的引用。
void push_back()
和void pop_back
是末尾插入和删除。
#include
using namespace std;
#include "vector"
int main(int argc, char *argv[])
{
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
cout<<"len:"< 0)
{
cout<
可以指定元素个数并初始化为0:vector
#include
using namespace std;
#include "vector"
int main(int argc, char *argv[])
{
vector v1(3); // vector v1(3,0)
v1.push_back(1);
cout<
除了vector
,还有其它带参数构造方式:
vector(iterator begin,iterator end)
,拷贝左闭右开区间[begin,end)
的元素vector(n,elem)
,拷贝n个elemvector(const vector &vec)
,拷贝构造函数vector v2 = v1;
vector v3(v1.begin(),v2.end() + 2);
#include
using namespace std;
#include "vector"
int main(int argc, char *argv[])
{
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
for(vector::iterator it = v1.begin(); it != v1.end(); it++)
{
cout<<*it<<" ";
}
cout<
v1.end()
仍然指向最后一个元素+1
.
反过来,还有rbegin(),rend()
#include
using namespace std;
#include "vector"
int main(int argc, char *argv[])
{
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
for(vector::reverse_iterator rit = v1.rbegin(); rit != v1.rend(); rit++)
{
cout<<*rit<<" ";
}
cout<
迭代器分为:
双向迭代器支持的操作:
it++,++it,
*it,
it1 = it2
it1 == it2, it1 != it2
支持的容器有list,set,multiset,map,multimap
随机访问迭代器在双向迭代器的基础上添加了以下操作:
it+=i,it[i]
it1
it1 = it2
it1 == it2, it1 != it2
支持的容器有vector,deque
.
vector.insert(iterator pos,elem);
vector.insert(iterator pos,int n,elem);
vector.insert(iterator pos,begin,end);
,在pos插入[begin,end)
区间的值。
vector.erase(iterator pos)
vector.erase(iterator begin,iterator end)
,删除一个区间。
注意,发生插入和删除时,vector的元素会移动,但迭代器不会改变所指向的位置。
#include
using namespace std;
#include "vector"
int main(int argc, char *argv[])
{
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(2);
v1.push_back(3);
vector::iterator it = v1.begin();
v1.erase(it);
v1.erase(it);
for(int i = 0; i < v1.size(); i++)
{
cout<