STL常见用法


STL常见用法

STL是一套非常好用的C++模板, 其中内置了很多已经封装好的数据结构和算法. 如果每次都要从头实现很麻烦, STL在刷算法题时候很好用. 本文是参照steve-yu视频做下的笔记.

输入输出

C++保留了原来C语言的输入和输出, 在基础上增加了cin和cout.

// 导入cin cout头文件
#include <iostream>
// c程序中输入输出
int a;
scanf("%d", &a);
printf("%d", a);
// C++输入输出
int a;
cin >> a;
cout << a;
// 连续输入输出变量
int a, b, c;
cin >> a >> b >> c;
cout << a<<b << c;
// 换行方便
cout << a<< endl;

cin和cout的效率是比scanf和printf低很多的, 在刷算法题时, 尽可能使用C语言的输入输出来避免超时.

头文件

在使用任意的STL数据类型前, 都需要导入对应的头文件. 比如说使用vector 就必须导入<vector>. <algorithm> 中有许多内置好的算法, 例如sort, reverse等.

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int a[]={2,1,5,0,-1,5,9};
    sort(a,a+7);
    for(int i=0;i<7;i++)
        cout<<a[i]<<" ";
    cout<<endl;
    system("pause");
    return 0;
}

String

字符串可以看做是char*的封装.

// c语言中的字符串定义和打印
char ch[]="asdkajbf";
for(int i=0;ch[i]!='\0';i++) printf("%c", *(ch+i));
// c++
string s = "zxcvbnm";
cout<< s <<endl;

获取一行字符串:

// c
scanf("%s", ch);
// c++
string s;
getline(cin, s);
cout << s;

还可以使用+= 运算, 数字会被转换成asc码.

string s;
s += "hello";
s += " world";
s += '5';
s += 10;//10对应的asc码是换行
int a = 5;//想把a加入字符串
s += (a+'0');
cout << s;

同样也可以进行排序:

string s = "5418340";
sort(s.begin(), s.end());
cout << s;

使用erasesubstr:

// erase
string s = "5418340";
s.erase(s.begin());//删除第一个
s.erase(--s.end());//删除最后一个
cout << s;
// substr
string s = "5418340";
s = s.substr(1, 3);//取418,取索引为1,往后截断3个
s = s.substr(1, -1);//索引为1,截断到最后
cout << s;

Vector

vector是封装好的向量, 类似数组. 使用前需导入vector头文件.

vector<int> v;//定义一个空vector
vector<int> v2(4);//定义一个4个大小的vector,初始为0
vector<int> v3(4,6);//定义一个4个大小的vector,初始为6
vector<int> v{1,2,3,4,5};//定义一个vector,数字为1,2,3,4,5

获取元素:

vector<int> v{1,2,3,4,5};
cout << v[1];//取索引为1
cout << v.at(2);//取索引为2的

// 获取第一个
cout<<v.front();
cout<<v[0];
cout<<*v.begin();
// 获取最后一个
cout<<v.back();
cout<<v[v.size()-1];//size是获取大小
cout<<*--v.end();

添加元素:

vector<int> v;
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(6);

修改形状:

v.resize(10);

删除元素:

v.erase(v.begin());//删除第一个元素
v.erase(--v.end());//删除最后一个元素

向量排序:

vector<int> v{5,1,2,5,4,0,-1};
sort(v.begin(),v.end(),less<int>());//从小到大
sort(v.begin(),v.end(),greater<int>());//从大到小排序

Stack

就是数据结构中的栈, 先进后出. 使用前需导入stack头文件.

stack<int> s;

栈的各种操作:

s.push(2); // 入栈
s.push(3);
cout << s.top() << endl; // 获取顶端
s.pop(); // 出栈 无返回值
cout << s.top() << endl;
cout << s.size() << endl; // 查看元素个数

用栈实现进制转换(decimal to binary):

int itob(int decimal){
    stack<int> s;
    int res = 0;
    while(decimal != 0){
        // 除二取余
        s.push(decimal%2);
        decimal /= 2;
    }
    while(!s.empty())}{
        res = res * 10 + s.top();
        s.pop();
    }
    return res;
}

用栈实现逆序单词打印:

#include <stack>
#include <sstream>

void inverse(string str){
    stack<string> s;
    stringstream ss;
    ss << str; // 让字符串流入stringstream
    while(ss >> str){
        s.push(str);
    }
    while(!s.empty()){
        cout << s.top();
        s.pop();
        if(s.size()!=0) cout << " ";
    }
}

这里使用了stringstream, 用来做数据转换, 十分安全和方便. 例如字符串转数字:

// 方法1
string s = "1234";
int i;
stringstream ss;
ss << s;
ss >> i;
cout << i;
// 方法2
string s = "1234";
int i = stoi(s);
cout << i;

数字转字符串:

// 方法1
int a = 1234;
string out;
stringstream ss;
ss << a;
ss >> out;
cout << out << endl;
//方法2(c++ 11)
int a = 1234;
cout << to_string(a) << endl;

Queue

此为队列的封装实现. 使用前需要导入<queue>.

queue<int> q;

其操作为:

q.push(5); //入队
q.push(6);
cout<<q.front()<<endl; // 取队首
q.pop(); // 出队
cout<<q.front()<<endl;
cout<<q.size()<<endl; // 查看队列已有元素长度

Map

map是一个映射关系(键值对). 这里的map分为两种, 一种是有序的map, 一种是无序的unordered_map. 使用前都需要分别导入.

map:

map<int,int> m;//有序, 底层为树状结构
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it=m.begin();it!=m.end();it++)
    cout<<it->first<<" "<<it->second<<endl;
for(auto tmp:m){
    cout<<tmp.first<<" "<<tmp.second<<endl;
}

unordered_map:

unordered_map<int,int> m;//无序, 底层为哈希结构
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it=m.begin();it!=m.end();it++)
    cout<<it->first<<" "<<it->second<<endl;
for(auto tmp:m){
    cout<<tmp.first<<" "<<tmp.second<<endl;
}

pair的用法, 是一个映射结构.

bool cmp(pair<int,int> a,pair<int,int> b){
    return a.first>b.first;
}
int main(){
    unordered_map<int,int> m;//无序, 底层为哈希结构
    m[6]=3;
    m[5]=8;
    m[4]=9;
    vector<pair<int,int>> v(m.begin(),m.end());
    sort(v.begin(),v.end(),cmp);
    for(auto tmp:v){
        cout<<tmp.first<<tmp.second<<endl;
    }
    return 0;
}

Set

它是集合的封装实现, 同样存在一种有序结构set和一种无序结构unordered_set. 使用前需要分别导入.

set<int> s;//树状结构 有序
unordered_set<int> s2;//哈希结构 无序
s.insert(3);
s.insert(4);
s.insert(4);
s.insert(4);
cout<<s.size()<<endl;
for(auto tmp:s)
    cout<<tmp<<" ";
cout<<endl;
for(auto it=s.begin();it!=s.end();it++)
    cout<<*it<<" ";
cout<<endl;

Deque

此为双端队列的封装实现, 使用前需要导入<deque>.

deque<int> d;
// 4 9 1 2
d.push_back(1); // 尾部添加
d.push_back(2);
d.push_front(9); // 首部添加
d.push_front(4);
d.pop_back(); // 尾部删除
d.pop_front(); // 头部删除
for(auto tmp:d) cout<<tmp<<endl;
for(auto it=d.begin();it!=d.end();it++) cout<<*it<<endl;
sort(d.begin(),d.end(),greater<int>()); // 排序

List

此为双向链表的实现, 使用前需要导入<list>.

list<int> li;
li.push_back(6); // 末尾插入
li.push_front(5); // 头部插入
li.emplace_front(9); // 也是头插
li.emplace_back(10); // 也是尾插
li.insert(++li.begin(),2); // 第一个元素后插入
for(auto tmp:li) cout<<tmp<<endl;
for(auto it=li.begin();it!=li.end();it++) cout<<*it<<endl;
//排序不能使用头文件algorithm中的sort 使用list模板自定义的sort方法
li.sort(greater<int>()); //从大到小排序

推荐阅读


文章作者: DaNing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 DaNing !
评论
 上一篇
C++之模板 C++之模板
C++之模板函数模板在C++中, 模板被用于设计可重用的软件, 模板提供了将通用数据类型作为参数的能力.比如有时, 在求一个最大值时, 不得不因为不同的数据类型而写许多除了数据类型外完全一致的代码: int maxValue(int va
2020-08-23
下一篇 
DL目标检测 DL目标检测
目标检测目标检测是CV里一个重要方向, 对于一张图片, 我们应该能够给出图中含有的物体(单个或多个)的位置以及他们的大小和类别. 目标定位假设我们已经能够利用CNN对一张图片是否含有某个物体而进行分类. 应该先搞清楚要的输出是什么. 在上
2020-08-18
  目录