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"