C++标准模板库(STL)常用介绍
1. 输入输出
C++既可以用C的scanf和printf,也可以用新增的的cin与cout,后者速度慢
1.1 C程序中输入输出
int a;
scanf("%d",&a);
printf("%d",a);
1.2 C++输入输出
int a;
cin >> a;
cout << a;
1.3 输入输出多个变量
int a,b,c;
cin >> a >> b >> c;
cout << a << b << c;
1.4 新增的换行
cout << endl;
2. algorithm头文件下常用函数
2.1 max()、min()、abs()/fabs()
#include<stdio.h>
#include<algorithm>
using namespce std;
int main(){
int x = 1, y = -2;
printf("%d %d\n", max(x, y), min(x, y)); // 输出 1 -2
printf("%d %d\n", abs(x), abs(y)); // 输出 1 2
return 0;
}
max(x, y)、min(x, y) 分别返回x和y中的最大、最小值,且参数必须是两个(可以是浮点数),参数为三个时可以写成max(x, max(y, z))
abs() 则是返回绝对值,需要注意的是只能传入整数,而浮点数对应的绝对值函数是 fabs()
2.2 swap()
int x = 1, y = 2;
swap(x, y);
cout << x << y; // 输出 2 , 1 交换 x y 的值
2.3 reverse()
reverse(it, it2) 注意的是左闭右开原则 , 翻转的范围是 [it, it2) . 可以方便的记后面加记就是反转几个
int a[10] = {1, 2, 3, 4, 5, 6, 7};
string s = "abcdefg";
reverse(a, a+4); // 输出 4 3 2 1 5 6 7
reverse(s, s+4); // 输出 "dcbaefg"
2.4 next_permutation()
输出序列在全排列中的下一个序列
int a[3] = {1, 2, 3};
do{
cout << a[0] << a[1] << a[2];
}while(next_permutation(a, a+3));
// 输出
//123
//132
//213
//231
//312
//321
注意 若达到全排列最后一个 返回的是false 对于循环退出判断很友好
2.5 fill()
类似memset ,但是不同于fill可以赋值数组类型对应范围中任意值
int a[5] = {1, 2, 3, 4, 5};
fill(a, a+5, 233);
// a[5] 变成 233,233,233,233,233
2.6 sort()
sort(首地址, 尾地址的下一个地址, 比较函数)
这里比较精髓的是比较函数的设定 可以不填,默认是非递减排列
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int a[]={2,3,5,0,-1,4,1};
sort(a,a+7);
for(int i=0;i<7;i++)
cout<<a[i]<<" "; // 输出 -1 0 1 2 3 4 5
return 0;
}
2.6.1 比较函数cmp
若对字符排序, 比较的是字典序 。greater<type>()
非递增 less<type>()
非递减
对于自定义的cmp 它的返回值为bool类型,简单来记 return a > b, 左边大 就是从大到小非递增,反过来小于号就是非递减
bool cmp(type a, type b){
if(xxx) return a > b;
return a < b;
}
同样适用于结构体,**vector, string, deque **
而set,map利用了红黑树实现,内部本身有序,不能使用sort
2.7 lower_bound() 和 upper_bound()
这两个必须用在有序数组或者容器之中。
lower_bound(first, last, val)
寻找[first, last) 依然是左闭右开原则,在此范围内第一个值大于等于val的元素的位置,若是数组,返回指针,若是容器,返回迭代器。(upper则是小于等于...)
用的较少且相对简单,不赘述。
3. vector
vector翻译为向量,叫做变长数组更好理解。
3.1 vector构造
vector<type> name;//定义一个空vector,type可以使int/double/char/结构体/其他容器
vector<int> v(3);//定义一个3个大小的vector,初始为0
vector<int> v1(3,6);//定义一个3个大小的vector,初始为6
vector<int> v2{1,2,3,4,5};//定义一个vector,数字为1,2,3,4,5
vector<vector<int>> name; //定义一个元素为vector的vector 类似变长二维数组
vector<type> arrName[size]; // 定义type类型的size大小的数组 arrName[x] 每个元素都是vector容器
3.2 访问vector
3.2.1 通过索引
vector<int> v{1,2,3,4,5};
cout << v[1]; // 取索引为1的 为2
cout << v.at(1); // 取索引为1的值 此处为2
3.2.2 通过迭代器
vector<int>::iterator it;
//还是上面的例子 那么: *(it + i) == v[i] == (v.begin()+i)
3.3 常用函数方法
3.3.1 push_back() 往后添加内容
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for(auto x:v) cout << x; //输出 12345
3.3.2 pop_back() 从后弹出/删除尾元素 时间复杂度O(1)
vector<int> v{1, 2, 3, 4, 5};
v.pop_back();
// 剩下 1, 2, 3, 4
3.3.3 resize() 重置大小
v.resize(10);//不赋值默认为0
3.3.4 clear() 清空vector所有元素 时间复杂度O(N) N为元素个数
v.clear()
3.3.5 insert(it, x) 在迭代器it处插入元素x 时间复杂度O(N)
vector v{1, 2, 3, 4, 5};
v.iinsert(v.begin() + 2, -1);
// 得到 1 2 -1 3 4 5
3.3.6 erase() 删除元素 可以是单个 也可以是 [区间) (左闭右开)
v.erase(v.begin()); //删除第一个元素
v.erase(first, last); //删除 [first, last) 左闭右开!
3.3.7 获取第一个元素,获取最后一个元素
/**获取第一个元素*/
cout << v.front();
cout << v[0];
cout << *v.begin();
/**获取最后一个元素*/
cout << v.back();
cout << v[v.size()-1];
cout << *--v.end();
3.3.8 find ( ) 函数
- algorithm中的find()函数,返回值是目标元素的下标,找不到时返回值为迭代器结尾
string = "hello";
find(s.begin(), s.end(), 'o'); // 等于最后一个元素
3.3.9 循环遍历相关
vector<int> v{5,1,2,5,4,0,-1};
for(int i=0;i<v.size();i++) cout<<v[i]; //for循环
for(vector<int>::iterator it=v.begin();it!=v.end();it++)
cout << *it;//迭代器循环
for(auto it=v.begin();it!=v.end();it++) cout << *it;//迭代器简化循环
for(auto x:v) cout << x;//c++11新特性
4. set 和 unordered_set
是一个内部自动有序且不含重复元素的容器。
set<type> name; // type类型的 有序
unordered_set<type> name2; //哈希结构 无序 更快
cout<<s.size(); // 计算set长度
// 遍历
for(auto x:s)
cout << x;
for(auto it=s.begin(); it!=s.end(); it++) // 通过迭代器 不能用 *(it + i)
cout<<*it;
其他 insert()
find()
erase()
clear()
用法与上面vector一致
5. string
存放字符的字符串 类似C里头的字符数组 char str[]
5.1 简单使用
5.1.1 定义
//C中定义字符串以及打印//
char *ch="abcdef";
for(int i=0; ch[i]!='\0'; i++) cout << *(ch+i); // 输出abcdef
//C++//
string s="asdfg";
s.size() == s.length(); // 都是返回长度
cout << s; // asdfg
5.1.2 读入字符串
string s;
getline(cin,s);//获取一行数据
5.2 常用函数
5.2.1 find() 相关
① find()
string str1, str2;
char c;
str1.find(str2); //从串str1中查找时str2,返回str2中首个字符在str1中的地址
str1.find(str2,5); //从str1的第5个字符开始查找str2
str1.find(c); //在str1中查找字符 c 并返回第一个查找到的地址
str1.find("str2" ,2, 2); //从str1中的第二个字符开始查找str2的前两个字符
②find_first_of()
函数原型:int find_first_of(char c, int start = 0);
这个用法和①中str1.find(str2)
相似,都是返回str2中首个字符在str1中的地址。
但是要特别注意,没有找到时返回值是-1.
③ find_last_of()
函数原型:int find_last_of(char c);
未找到时返回-1。
④ find_not_first_of()
函数原型:size_type find_first_not_of(char ch, size_type index = 0 );
在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如 果没找到就返回string::nops。
⑤ find_not_last_of()
函数原型:size_type find_last_not_of(char ch, size_type index = 0 );
在字符串中查找最后一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。 如果没找到就返回string::nops。
5.2.2 operator+=
+=直接把两个string拼接起来
string s;
s += "hello";
s += " world"; // 此时 s = hello world
s += 10; // 此时10对应ascii码==换行
int a = 2; // int a加入字符串 需要转为字符
s += (a + '0');
5.2.3 排序
string s="541230";
sort(s.begin(),s.end()); // 012345
5.2.4 erase()函数
和vector一致
// begin是头迭代器,end是尾迭代器 //
string s="5352567";
s.erase(s.begin());//删除第一个
s.erase(--s.end());//删除最后一个
5.2.5 compare operator
==、!=、<、<=、>、>= 比的是字典序的大小
string str1 = "aa", str2 = "aaa", str3 = "abc", str4 = "xyz";
//此时 str1 < str2;
// str1 != str2;
// str4 >= str3;
5.2.6 substr()函数
//begin() 头迭代器,end() 尾迭代器//
string s="567318340";
s = s.substr(1,3); // 得673 意思是索引从1开始 往后取3位
s = s.substr(1,-1); // 索引1 也就是从头开始 取到最后
5.2.7 string::npos
为一个常数,本身为-1,但是为unsigned_int类型 可以认为是其类型的最大值
5.2.8 replace()
str.replace(pos, len, str2)
把str从pos开始,长度为len的子串替换为str2
str.replace(it1, it2, str3)
把str迭代器 [it1, it2) 依旧是左闭右开 替换为str3
5.2.9 访问方式(3种)
1.for循环
string s="5193840";
for(int i=0;i<s.length();i++) cout<<s[i]; ///5193840
2.迭代器
for(string::iterator it=s.begin(); it!=s.end();i t++) cout << *it;
for(auto it=s.begin();it!=s.end();it++) cout << *it;
3.利用C++ 11新特性for循环
for(auto x:s) cout << x;
5.2.10 stoi 函数
stoi(字符串,起始位置,n进制),将 n 进制的字符串转化为十进制
stoi(str, 0, 2); //将字符串 str 从 0 位置开始到末尾的 2 进制转换为十进制
stoi(str); //默认str全转为十进制
5.2.11 atoi( ) 函数
int atoi (const char *str );
把字符串转换成整型数。
参数str:要进行转换的字符串
返回值:每个函数返回 int
值,此值由将输入字符作为数字解析而生成。 如果该输入无法转换为该类型的值,则atoi的返回值为 0。
5.2.12 c_str ( )
将C++的string转化为C的字符串数组,c_str()生成一个const char *指针,指向字符串的首地址
char *p=s[10];
string a=“hello world”;
strcpy(p, a.c_str());
cout << p; //结果为 "hello world"
5.2.13 strcpy(a, b) 字符串复制
把字符串b 复制到 a
5.2.14 reverse()
reverse()
反转字符串
6. map 和 unordered_map
映射关系 键值对 像python里的字典(map为树状表,unorderedmap为哈希表 更快)
6.1 map<type, type> name
map<int,int> m; //有序
m[6]=3;
m[5]=2;
m[4]=1;
// 通过迭代器访问
for(auto it=m.begin();it!=m.end();it++)
cout << it->first << “-” << it->second;
for(auto t:m)
cout << t.first << "-" << tmp.second;
//输出 4-1 5-2 6-3 按照键的大小 从小到大排序 和set一样内部用红黑树实现
6.2 unordered_map<type, type> name
unordered_map<int,int> m; //无序
m[3]=3;
m[2]=8;
m[1]=9;
//迭代器访问
for(auto it=m.begin();it!=m.end();it++)
cout<<it->first<<"+"<<it->second<<endl;
for(auto t:m)
cout<<t.first<<"+"<<t.second<<endl;
// 此时输出为无序(按照某种序的无序)
此外还可以通过下标访问,因为map的健是唯一的
map<char, int> m;
m['a'] = 1;
cout << m['a']; // 为 1
6.3 其他函数方法
find()
erase()
size()
clear()
都和上述vector,string 用法一致。
7. queue 和 priority_queue
queue为先进先出的队列 priority_queue为优先队列
queue<type> name
定义一个name名type类型的队列
7.1 访问及常用函数
push(x) 将x推进队列
front()访问获得队首元素 back()获得队尾元素
pop()队首元素出队
q.push(2); // 2
q.push(3); // 3 2
cout << q.front(); // 2
cout << q.back(); // 3
q.pop(); // 弹出2 队内剩 3
cout << q.front(); // 3
7.2其他函数
empty()
size()
也和其他容易的用法一致。
7.3 优先队列的访问
有限队列的定义是和普通队列一样的
但是访问没有front() back() 只能通过 top() 访问队首元素 也就是优先级最高的元素
pop()
empty()
size()
用法也一致
重点在这 优先级的设置
7.4 优先队列的优先级
priority_queue<int> q
默认写法 优先级就是数字越大、字符字典序越大的优先级越大!
priority_queue<int, vector<int>, less<int>> q
这种写法第二个参数是承载底层数据结构堆(heap)的容器,所以第二个参数vector的数据类型要与第一个参数一致 这里是int 第三个参数则是比较序 less表示数字大优先级大 greater相反
7.5 结构体优先级 及 重构
struct fruit{
string name;
int price;
friend bool operator < (fruit f1, fruit f2){
return f1.price < f2.price;
}
};
这里用friend友元重构了小于号< 使结构体fruit会以价格高的为优先级高
同理 若是要价格高的优先级低 则return里 小于改为大于号即可
这里的重构 恰好和sort中cmp的是相反的! sort里return f1.price>f2.price
则是按价格从高到低排序 下面方法则是把重构写成类似cmp
struct cmp{
bool operator () (fruit f1, fruit f2){
return f1.price > f2.price;
}
};
//此时定义优先队列
priority_queue<fruit, vector<fruit>, cmp> q; // 其实效用==greater<fruit>
延伸:重构可以用在其他STL容器(set)定义优先级大幅提升效率
8. deque
双端队列deque <type> name
deque<int> d;
// 前后 push进 pop出与vector一致
d.push_back(1);
d.push_front(4); // 此时d中 4 1
d.pop_back();// 弹出1
d.pop_front(); // 弹出4
//遍历
for(auto tmp:d) cout << tmp;
for(auto it=d.begin();it!=d.end();it++) cout << *it;
同时也支持sort()
resize()
insert()
erase()
用法和其他容器一致
9. stack 栈
9.1 定义栈及简单操作
- 只能通过top()访问栈顶元素
stack<int> s; // 定义一个 int 型 名为 s 的栈
// push进栈
s.push(2);
s.push(3);
// 获取栈顶的值
cout << s.top(); // 此时为 2
// 出栈一个元素 无返回值
s.pop(); // 弹出2
cout << s.top(); // 此时为3
// 栈的长度
cout << s.size(); // 为 1
// empty()判断栈是否为空
if(s.empty() == true) cout << true;
else cout << false; // 此时返回false
9.2 进制转换 (十进制转二进制)
利用栈比较经典的做法 除2取余 逆序排列 用栈太合适了
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;
}
9.3 sstream 与 字符串与数字互转
stringstream 对象用于输入一行字符串,以 空格 为分隔符把该行分隔开来
- 字符串转数字
方法1: 利用sstream
string s="1234";
int i;
stringstream ss;
ss << s;
ss >> i;
方法2: 直接利用stoi ()函数
string s="1234";
int i = stoi(s); // stoi函数 将n进制转为十进制
- 数字转字符串
方法1: sstream
int a = 1234;
string out;
stringstream ss;
ss << a;
ss >> out;
方法2: C++ 11 最新 to_string()
方法
int a = 1234;
cout << to_string(a);
例题 PAT B1009 可以利用 ssteam 简化 PAT-B1009 说反话 - 字符串反转
10. pair
pair<type1, type2> name; 是将两个元素捆绑成一个元素 成为结构体的替代品 实质都一样
10.1 pair的定义、添加、访问
pair有两个元素 first/second,还需要记住一个自带的make_pair
函数
pair<string, int> p;
// 第一种添加方式
pair<string, int> p("xixi", 3);
// 第二种方式
p.first = "haha";
p.second = 123;
// 利用make_pair
p = make_pair("hoho", 5);
// pair的输出
cout << p.first << " " << p.second;
10.2 pair元素的比较
两个pair类型可以直接用 ==、!=、<、<=、 >、 >=
比较规则是先比较first的大小,只有当first相等是才比较second的大小 (默认由小到大排序)
10.3 pair的用法实例 (map转成vector进行排序)
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]=2;
m[4]=1;
vector<pair<int,int>> v(m.begin(),m.end()); // 把映射关系加入到向量中
sort(v.begin(), v.end(), cmp); // 排序
for(auto t:v){
cout << t.first << t.second << endl;
}
return 0;
}
// 输出
// 63
// 52
// 41
11. list
双向链表 比起vector , list支持快速插入和删除, 但是随机访问比较慢
list<int> l; // 初始化
l.push_back(1); // 尾部输入一个1
l.push_front(3); // 头部输入一个3
// C++11 新增加的emplace 类似于push
l.emplace_front(2);
l.emplace_back(4);
// 插入
l.insert(pos,eN,ele); // pos开始位置,eN为插入元素数,不填默认1,ele 为插入的元素
// 访问
for(auto t:li) cout << t;
for(auto it=li.begin(); it!=li.end(); it++) cout << *it;
pop_back()
pop_front()
size()
empty()
erase()
clear()
front()
back()
swap()
reverse()
sort()
也和其他容器用法一致
12. 文档
更详细的方法查文档
中文:http://c.biancheng.net/stl/
英文:http://www.cplusplus.com/reference/stl/
13. 万能头文件
嘿 写在最后就是怕一开始就用这个偷懒,其实用到什么打上对应头文件最后看到一列头文件还别有一番感觉,但是..万能头文件确实更方便
#include <bits/stdc++.h>
C++标准模板库(STL)常用介绍的更多相关文章
- C++_标准模板库STL概念介绍1-建立感性认知
标准模板库的英文缩写是STL,即Standard Template Library. STL里面有什么呢? 它提供了一组表示容器.迭代器.函数对象和算法的模板. 容器是一个与数组类似的单元,可以存储若 ...
- C++_标准模板库STL概念介绍5-其他库与总结
C++还提供了其他一些类库,这些类库更加专用. 例如,头文件complex为复数提供了类模板complex,包含用于float.long和long double的具体化. 这个类提供了标准的复数运算以 ...
- C++_标准模板库STL概念介绍4-算法
STL包含很多处理容器的非成员函数: sort() copy() find() random_shuffle() set_union() set_intersection() set_differen ...
- C++_标准模板库STL概念介绍2-泛型编程
有了之前使用STL的经验后,接下来讨论泛型编程及其底层的理念: 首先我们知道STL只是泛型编程的一种: 而面向对象的编程方式关注的是编程的数据方面: 而泛型编程关注的是算法: 但是,他们之间的一个重要 ...
- C++_标准模板库STL概念介绍3-函数对象
函数对象也叫做函数符(functor). 函数符是可以以函数方式和( )结合使用的任意对象. 包括函数名,指向函数的指针,重载了()运算符的类对象. 可以这样定义一个类: class Linear { ...
- STL学习系列之一——标准模板库STL介绍
库是一系列程序组件的集合,他们可以在不同的程序中重复使用.C++语言按照传统的习惯,提供了由各种各样的函数组成的库,用于完成诸如输入/输出.数学计算等功能. 1. STL介绍 标准模板库STL是当今每 ...
- C++ 标准模板库STL 队列 queue 使用方法与应用介绍
C++ 标准模板库STL 队列 queue 使用方法与应用介绍 queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数, ...
- 标准模板库--STL
标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic progra ...
- C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用
摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动 ...
- 标准模板库(STL)学习探究之stack
标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string
随机推荐
- 记录一次线上实施snmp
公司要实施一个部级的项目,我们公司的提供的产品要对接下客户的一个平台监控平台,该监控平台使用snmp,我们公司的产品不支持snmp,所以由我负责在现网实施snmp,记录这次现网 一.生成编译规则 1. ...
- heap相关算法的简单实现
// 12:06 PM/09/28/2017 #pragma once //向下调整算法 主要用来make_heap 以及pop_heap inline void adjustDown(int* he ...
- CAS(乐观锁)以及ABA问题
https://blog.csdn.net/wwd0501/article/details/88663621独占锁是一种悲观锁,synchronized就是一种独占锁:它假设最坏的情况,并且只有在确保 ...
- 002_解析go语言中的回调函数
回调函数是一种特殊的函数写法,在很多场景中发挥广泛的作用.但是对于初学者来说,回调函数是比较头疼的一个东西,不太好懂,笔者研究了一番,以网上的一个例子详细说明一下 首先看一个代码示例(来源于网上) p ...
- 001_解析go语言中的闭包
go语言中的闭包,是大家学习go语言的一个大难点,笔者在学习时候也是痛苦不堪,在来回对比了其它语言的用法,并且查阅了很多网上的文章,终于对闭包有了一个较为清晰的认识,以下就是关于闭包的解析 首先看一个 ...
- VMware启动CentOS出错,提示"该虚拟机似乎正在使用中"
今天在使用VMware启动CentOS时,出现如下图1错误提示: 当点击“确定”按钮时,出现如下图2错误提示: 无奈,只能点击图1 中的“取消”按钮,进行问题的跟踪.分析.经过核实,发现上述问题是由于 ...
- JavaScript重定向
使用JavaScript重定向到其他网页的一些方法: location.href location.replace() location.assign() 语法: window.location.hr ...
- JavaScript npm/nrm 切换安装依赖的镜像源
nrm: npm registry manager npm 镜像源管理工具 安装nrm npm install -g nrm 查看所有的镜像源 nrm ls # nrm ls npm -------- ...
- Umlet和draw.io 使用心得
文章目录 软件使用心得 1. Umlet 画图软件 1.1 前言 1.2 优点 1.3使用小trick 1.3.1 灵活改变箭头形式 1.3.2 整体复制 1.3.3 快速复制 2. draw.io ...
- 详解Python Graphql
前言 很高兴现在接手的项目让我接触到了Python Graphql,百度上对其介绍相对较少也不够全面,几乎没有完整的中文文档,所以这边也借此机会学习一下Graphql. 什么是Graphql呢? Gr ...