【C++】STL

目录

前言

1. 模板

1.1 函数模板

1.2 类模板

2. 常用容器

2.1 string容器(字符串)

2.1.1 基本操作

2.1.2 基本语法

2.2 vector容器(变长数组)

2.2.1 基本操作

2.2.2 基本语法

2.3 list容器(双向链表)

2.3.1 基本操作

 2.3.2 基本语法

2.4 queue容器(队列)

2.4.1 基本操作

2.4.2 priority_queue(优先级队列)

2.5 stack(栈) 

3. 常用算法

3.1 sort(排序)


前言

STL即 Standard Template Library (标准模板库)的缩写,是C++自带的函数库,里面包含一些可以直接使用的类或者函数。例如 sort(排序)、string(字符串)、vector(变长数组)、list(双向链表)、map(key-value对应关系)、set(集合)、queue(队列)、priority_queue(优先级队列)、stack(栈)等。

1. 模板

1.1 函数模板

所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)

template<typename T> //此时可以把T当做一种类型
void Swap(T &a, T &b)//当时用该函数的时候,编译器会根据参数类型自动判断T是什么类型
{
    T temp = a;
    a = b;
    b = temp;
}//建议直接使用自带的函数swap()

int main(){
    //交换 int 变量的值
    int n1 = 100, n2 = 200;
    Swap(n1, n2);
    cout<<n1<<", "<<n2<<endl;
   
    //交换 float 变量的值
    float f1 = 12.5, f2 = 56.93;
    Swap(f1, f2);
    cout<<f1<<", "<<f2<<endl;
   
    //交换 char 变量的值
    char c1 = 'A', c2 = 'B';
    Swap(c1, c2);
    cout<<c1<<", "<<c2<<endl;
   
    //交换 bool 变量的值
    bool b1 = false, b2 = true;
    Swap(b1, b2);
    cout<<b1<<", "<<b2<<endl;

    return 0;
}

1.2 类模板

函数模板中定义的类型参数可以用在函数声明和函数定义中,类模板中定义的类型参数可以用在类声明和类实现中。类模板的目的同样是将数据的类型参数化。一但声明了类模板,就可以将类型参数用于类的成员函数和成员变量了。换句话说,原来使用 int、float、char 等内置类型的地方,都可以用类型参数来代替。

注意:

1. 使用类模板创建对象时,需要指明具体的数据类型。请看代码:Point<int, int> p1(10, 20);

2. 与函数模板不同的是,类模板在实例化时必须显式地指明数据类型,编译器不能根据给定的数据推演出数据类型。Point<int, int> p1(10, 20);

3. 赋值号两边都要指明具体的数据类型,且要保持一致。                                                    Point<char*, char*> *p3 = new Point<char*, char*>("东经180度", "北纬210度");

假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数、小数和字符串,例如:

  • x = 10、y = 10
  • x = 12.88、y = 129.65
  • x = "东经180度"、y = "北纬210度"
#include <iostream>
using namespace std;

template<class T1, class T2>  //这里不能有分号
class Point{
public:
    Point(T1 x, T2 y): m_x(x), m_y(y){ }
public:
    T1 getX() const;  //获取x坐标
    void setX(T1 x);  //设置x坐标
    T2 getY() const;  //获取y坐标
    void setY(T2 y);  //设置y坐标
private:
    T1 m_x;  //x坐标
    T2 m_y;  //y坐标
};

template<class T1, class T2>  //模板头
T1 Point<T1, T2>::getX() const /*函数头*/ {
    return m_x;
}

template<class T1, class T2>
void Point<T1, T2>::setX(T1 x){
    m_x = x;
}

template<class T1, class T2>
T2 Point<T1, T2>::getY() const{
    return m_y;
}

template<class T1, class T2>
void Point<T1, T2>::setY(T2 y){
    m_y = y;
}

int main(){
    Point<int, int> p1(10, 20);
    cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl;
 
    Point<int, char*> p2(10, "东经180度");
    cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl;
 
    Point<char*, char*> *p3 = new Point<char*, char*>("东经180度", "北纬210度");
    cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl;

    return 0;
}

2. 常用容器

2.1 string容器(字符串)

2.1.1 基本操作

//1.使用
string str; //默认为“”空字符串
string str1="hello"; //初始化为“hello”

//2.输入
cin>>str; //读入一个串(空格为中间符)abc cd   只读入abc
getline(cin,str); //读入一行。abc cd 全部读入

//3.输出
cout<<str; //输出整个string
cout<<str[0]; //输出string第一个字符

2.1.2 基本语法

赋值运算符:= o(n)
比较运算符:== != < <= > >=按字典序比较o(n)                                                                                连接运算符:+ +=将第二个串拼接到第一个后面o(n)
s[index]返回字符串s中下标为index的字符(下标从0开始)o(1)                                        s.substr(p,n)返回从s的下标p开始的n个字符组成的字符串o(n)                                                          s.length返回字符串的长度O(1)
s.empty()判断s是否为空o(1)
s.erase(p0,len)删除s中从p0开始的len个字符,如果len省略则删除p0及后面全部字符o(n)
s.erase(s.begin( )+i)删除前i个字符o(n)
s1.find(s2,pos)从前往后,查找成功时返回第一次出现的下标,失败返回                                    string : :npos的值(-1) o(n*m)

2.2 vector容器(变长数组)

2.2.1 基本操作

vector是能够存储多个相同类型元素的容器(类似于数组)

//声明:
template<
    class T,
    class Allocator = std::allocator<T>
>class Vector;

//使用
vector<int> vec;//一个存储int类型的vector,默认size是0
vector<int> vec(n);//一个存储int类型变量的vector,size为n

//输入:
//1.size为0:
cin>>tem;//读入
vec.push_back(tmp);//将tmp推入vec的末尾
//2.size为n
cin>>vec[i];//写入vec的第i个元素(下标从0开始)

//输出
for(int i=0;i<vec.size();i++) cout<<vec[i];//vec.size()为vec内元素个数
for(auto it:vec) cout<<it;//range-based loop

2.2.2 基本语法

v[i] 返回v中第i个元素(下标从0开始) o(1)
v.push_back(var) 向v后面添加一个元素var o(1)                                                                        v.pop_back() 删除v最后一个元素o(1)
v.size() 获取v中元素个数,返回size_t类型变量o(1)                                                                           v.resize(int n) 把v的容量改为n个元素o(n)
v.empty() 判断v是否为空o(1)
v.clear() 清空v o(size)
v.insert(it,x) 向迭代器it指向元素前增加一个元素x o(n)                                                                      v.erase(it) 删除向量中迭代器指向元素o(n)
v.front() 返回首元素的引用o(1)
v.back() 返回尾元素的引用o(1)
v.begin() 返回指向第一个元素的迭代器o(1)
v.end() 返回指向最后一个元素的下一个位置迭代器o(1)

2.3 list容器(双向链表)

2.3.1 基本操作

list是由双向链表实现的存储容器。

//声明:
template<
class T,
class Ailocator = std: :allocator<T>
>class list;

//使用:
list<int> lis; //一个存储int类型变量的list,默认size为空

//插入:
//前端插入:
lis.push_front(item); //从list前端插入
//后端插入:
lis.push_back(item); //从list后端插入
//中间插入:
auto it=find(iis.begin(),lis.end(),val);
if(it!=lis.end()) lis.insert(it,item); //找到list中第一个值为val的元素,插入到其前方

//输出:
for(auto it=lis.begin();it!=lis.end();it++) cout<<*it;
for(auto it:lis) cout<<it; //range-based loop

 2.3.2 基本语法

lis.push_front(var) 向lis前面添加一个元素var o(1)                                                              lis.push_back(var) 向lis后面添加一个元素var o(i)                                                                  lis.pop_front() 删除lis第一个元素o(1)
lis.pop_back() 删除lis最后一个元素o(1)
lis.size()获取lis中元素个数,返回size_t类型变量o(1)                                                                    lis.resize(int n) 把lis的容量改为n个元素o(n)
lis.empty() 判断v是否为空o(1)
lis.clear() 清空lis o(size)
lis.insert(it,×) 向迭代器it指向元素前增加一个元素x o(1)                                                                  lis.erase(it) 删除向量中迭代器指向元素o(1)
lis.front() 返回首元素的引用o(1)
lis.back() 返回尾元素的引用o(i)
lis.begin() 返回指向第一个元素的迭代器o(1)
lis.end()返回指向最后一个元素的下一个位置迭代器o(1)

2.4 queue容器(队列)

队列是一种先进先出的数据结构

2.4.1 基本操作

//声明:
template<
    class T,
    class Container = std::deque<T>
> class queue;

//使用:
queue<int> q; //建立一个存储int类型的队列q使用方法:
q.push(item) //在q的最后添加一个type类型元素item o(1)
q.pop() //使q最前面的元素出队o(1)
q.front() //获取q最前面的元素o(1)
q.size() //获取q中元素个数o(1)
q.empty() //判断q是否为空o(1)

2.4.2 priority_queue(优先级队列)

优先级队列按照元素的优先级顺序,从高到低弹出元素

//声明:
template<
    class T,
    class Container = std:: vector<T> ,
    class compare =std::less<typename container ::value_type>
    class priority_queue;

//使用:
priority_queue<int> pq; //建立一个存储int类型的优先级队列pq使用方法:

pq.push(item) //在pq中添加一个元素item o(1ogn)
pq.pop() //使pq最前面的元素出队o(1)
pq.front() //获取pq最前面的元素o(logn)
pq.size() //获取pq中元素个数O(1)
pq.empty() //判断pq是否为空o(1)

2.5 stack(栈) 

栈是一种先进后出的数据结构

//声明:
template<
    class T,
    class Container = std::deque<T>
> class stack;

//使用:
stack<int> s;建立一个存储int类型的栈s

使用方法:
s.push(item) //在s的顶层压入一个type类型元素item o(1)
s.pop() //使s最上层的元素出栈o(1)
s.top() //获取s最上层的元素o(1)
s.size() //获取s中元素个数o(1)
s.empty() //判断s是否为空o(1)

3. 常用算法
 

3.1 sort(排序)

声明:

template <class RandomIt,class Compare>
void sort(RandomIt first,RandomIt last,Compare comp);

使用:

int a[ ]={3,5,6,7,8,4,2,1,9}
sort(a,a+9); //默认是从小到大
//1,2,3,4,5,6,7,8,9

int a[ ]={3,5,6,7,8,4,2,1,9}
sort(a,a+9,1ess<int>()); //从小到大
//1,2,3,4,5,6,7,8,9

int a[]={3,5,6,7,8,4,2,1,9}
sort(a,a+9,greater<int>()); //从大到小
//9,8,7,6,5,4,3,2,1


bool cmp(int a,int b){
    return a<b;
}
int a[ ]={3,5,6.7,8,4,2,1,9};
sort(a, a+9, cmp); //从小到大1,2,3,4,5,6,7,8,9
bool cmp(int a,int b){
return a>b;
}

int a[ ]={3,5,6,7,8,4,2,1,9}
sort(a, a+9,cmp); //从大到小
//9,8,7,6,5,4,3,2,1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值