由于CCF认证考试迫在眉急,赶快开始学习STL以应对考试,希望能获得200+,希望希望。
在B站找到的视频归纳,感谢up主 @steve-yu,<-_^>
文章目录
库函数的认识
1.algorithm翻译:算法
一个STL中很重要的库函数
1.1sort
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[] = { 1, -3, 5, 64, 2, 14, 0 };
sort(a, a + 7);
for (int i = 0; i < 7; i++)
cout << a[i] << ' ';
cout << endl;
return 0;
}
1.2.next_permutation
STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation。
主要思想:
按照字典序排序一个序列。该序列的每个元素不变,下一个会比前一个大一点。(perv_permutation正好相反)
eg.[1,1,3,2,3,2]->[1,1,3,3,2,2]
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int sum = 1; //1234算作第一种
int ans[4] = { 1, 2, 3, 4 };
sort(ans, ans + 4);
while (next_permutation(ans, ans + 4))
{
for (int i = 0; i < 4; ++i)
cout << ans[i] << " ";
cout << endl;
sum++;
}
cout << sum;//24
return 0;
}
2.string
常用的构造函数
string(); // 默认构造函数,建立一个长度为0的串
例:
string s1;
string(const char *s); // 用指针s所指向的字符串常量初始化string对象
例:
string s2 = "abc";
string(const string& rhs); // 复制构造函数
例:
string s3 = s2;
常用操作
s + t 将串s和t连接成一个新串
s = t 用t更新s
s == t 判断s和t是否相等
s != t 判断s和t是否不等
s < t 判断s是否小于t(按字典顺序比较)
s <= t 判断s是否小于或等于t(按字典顺序比较)
s > t 判断s是否大于t(按字典顺序比较)
s >= t 判断s是否大于或等于t(按字典顺序比较)
s[i] 访问串中下标为i的字符
2.1.C中的char*进行封装为stl的C++有string
/*C语言*/
char ch[] = "zifuchuan";
for (int i = 0; ch[i] != '\0'; i++)
cout << *(ch + i);
/*C++语言*/
string ch = "zifuchuan";
cout << ch << endl;
2.2.getline(cin, str)
/*C语言*/
char ch[100];
scanf("%s", ch); // 仅获取一个单词,以空格结束
printf("%s", ch);
/*C++语言*/
string s;
getline(cin, s);
cout << s << endl;
2.3.+=介绍
+=对于字符串、字符有效,数字会转为ASCII码
string s;
s += "hello";
s += ' world';
s += 10; // 10对应的ASCII是换行
s += '4';
int a = 5; // 想把a添加到字符串中
// s += a; ×
s += (a += '0');
cout << s;
/* 输出结果应该是
hello world
45
*/
2.4.排序(通过algorithm)
// begin是头迭代器,end是尾迭代器
string s = "5932871064";
cout << *s.begin() << endl; // 从第一个开始排序
cout << *--s.end() << endl; // 从最后一个4的后一个开始排序,所以进行自减操作
sort(s.begin(), s.end());
cout << s << endl;
/*
5
4
0123456789
*/
2.5.erase函数
string s = "5932871064";
s.erase(s.begin());
s.erase(--s.end());
cout << s << endl;
/*输出s是93287106*/
2.6.substr函数
string s = "5932871064";
s = s.substr(1, 3); // 取932,取索引为1,往后截断3个
s = s.substr(5, -1); // 索引为1,截断到最后
cout << s << endl;
/* 假如两种情况是孤立的,那么输出结果分别是
932
71064
*/
2.7.循环方式(4种)
2.7.1.for循环
for (int i = 0; i < s.length(); i++) cout << s[i];
2.7.2.迭代器
// 这里用了迭代器,而且前面标注是string类型的迭代器。这里的it是一个变量,类似python的each
for (string::iterator it = s.begin(); it != s.end(); it++) cout << *it;
2.7.3.迭代器化简
// auto可以代替任何一种类型的迭代器
for (auto it = s.begin(); it != s.end(); it++) cout << *it;
2.7.4.利用C++11新特性for循环
for (auto a : s) cout << a;
输入整行字符串
- getline可以输入整行字符串(要包含string头文件)。
例如:
getline(cin, s2); // cin表示读入键盘输入,后面会讲到io等。
- 输入字符串事,可以使用其他分隔符作为字符串结束的标志(例如分号、逗号),而普通的只能规定为" "。将分隔符作为getline的第3个参数即可。
例如:getline(cin, s2, ',');
#include <iostream>
#include <string>
using namespace std;
int main()
{
for (int i = 0; i < 2; i++)
{
string city, state;
getline(cin, city, ',');
getline(cin, state);
cout << "City:" << city << " State:" << state << endl;
}
return 0;
}
/*
Beijing,China
City:Beijing State:China
San Francisco,the United States
City:San Francisco State:the United States
*/
小例子:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string s, a;
getline(cin, s);
cout << s << endl;
s += 10;
a = s.substr(1, 4);
cout << a << endl;
for (int i = 0; i < s.length(); i++) cout << s[i];
cout << endl;
s += "95346";
s.erase(s.begin());
for (string::iterator it = s.begin(); it != s.end(); it++) cout << *it;
cout << endl;
sort(s.begin(), s.end());
for (auto it = s.begin(); it != s.end(); it++) cout << *it;
cout << endl;
s += "6";
for (auto x : s) cout << x;
cout << endl;
/*
5932871064
5932871064
9328
5932871064
932871064
95346
01233445667899
012334456678996
*/
return 0;
}
例子2:
string s1 = "abc", s2 = "def";
string s3 = s1 + s2; // 结果是"abcdef"
bool s4 = (s1 < s2); // 结果是true
char s5 = s2[1]; // 结果是'e'
#include <iostream>
#include <string>
using namespace std;
// 根据value的值输出true或false
// title为提示文字
inline void test(const char* title, bool value)
{
cout << title << "returns" << (value ? "true" : "false") << endl;
}
int main()
{
string s1 = "DEF";
cout << "s1 is " << s1 << endl;
string s2;
cout << "Please enter s2: ";
cin >> s2;
cout << "length of s2: " << s2.length() << endl;
// 比较运算符的测试
test("s1 <= \"ABC\"", s1 <= "ABC");
test("\"DEF\" <= s1", "DEF" <= s1);
// 连接运算符的测试
s2 += s1;
cout << "s2 = s2 + s1: " << s2 << endl;
cout << "length of s2: " << s2.length() << endl;
return 0;
}
/*
s1 is DEF
Please enter s2: wearetheworld
length of s2: 13
s1 <= "ABC"returnsfalse
"DEF" <= s1returnstrue
s2 = s2 + s1: wearetheworldDEF
length of s2: 16
*/
3.vector
3.1.vector构造
// vector是一个容器,可以理解为一个数组
vector<int> v1; // 定义一个空vector
vector<int> v2(4); // 定义一个4个大小的vector,初始化为0,即可以输出4个0
vector<int> v3(4, 6); // 定义一个4个大小的vector,初始化为6,即可以输出4个6
vector<int> v4{ 1,2,3,4,5 }; // 定义一个vector,数字为1,2,3,4,5
// 输出是用auto方法
for (auto x : v2) cout << x;
3.2.用at或者[]获取元素
vector<int> v{ 1,2,3,4,5 };
cout << v[1]; // 取索引为1的
cout << v.at(2); // 取索引为2的
3.3.方法
3.3.1.push_back追加内容
vector<int> v;
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(5);
for (auto x : v) cout << x;
3.3.2.resize进行重置大小
v.resize(10); // 不赋值默认将多出来的部分初始化为0
3.3.3.erase删除元素,复杂度为O(n)
v.erase(v.begin()); // 删除第一个元素
v.erase(--v.end()); // 删除最后一个元素
3.3.4.获取第一个元素,获取最后一个元素
vector<int> v;
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(6);
v.push_back(10);
/*获取第一个元素*/
cout << v.front();
cout << v[0];
cout << *v.begin();
/*获取最后一个元素*/
cout << v.back();
cout << v[v.size() - 1]; // size()能够获取vector大小
cout << *--v.end();
cout << "\n\n";
cout << v.size();
/*
555101010
6
*/
3.4.排序
第三个参数不写默认为less<int>()
vector<int> v{ 5,9,3,2,8,7,1,0,6,-1 };
sort(v.begin(), v.end(), less<int>()); // 从小到大
sort(v.begin(), v.end(), greater<int>()); // 从大到小
for (auto x : v) cout << x;
3.5.循环
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.stack
4.1.stack构造
stack<int> s;
4.2.push/pop/top/size/empty
- push:入栈一个元素
- pop:出栈一个元素,pop无返回值
- top:取栈顶元素
- size:获取元素个数
stack<int> s;
s.push(2);
s.push(3);
cout << s.size() << endl; // 2 stack中有两个元素
cout << s.top() << endl; // 3 最顶的元素是3(后用push放进去的)
s.pop();
cout << s.size() << endl; // 1 使用pop出栈一个元素之后
cout << s.top() << endl; // 2 最顶的变成了2
4.3.进制转化
十进制转二进制
int itob(int decimal)
{
stack<int> s;
int res = 0;
// 转化为2进制
while (decimal != 0) {
s.push(decimal % 2);
decimal /= 2;
}
// 将数组转化为二进制表达
while (!s.empty()) {
res = res * 10 + s.top();
s.pop();
}
return res;
}
4.4.逆序单词
输入一行字符串,将字符串逆序打印
// include <sstream>
string str;
stack<int> s;
getline(cin, str);
stringstream ss;
ss << str;
while (ss >> str)
s.push(str);
while (!s.empty()) {
cout << s.top();
s.pop();
if (s.size() != 0)
cout << " ";
}
4.5.字符串转数字
- 方法1(需要头文件<sstream>)
string s = "1234";
int i;
stringstream ss;
ss << s;
ss >> i;
cout << i;
- 方法2
string s = "1234";
int i = stoi(s);
cout << i;
4.5.数字转字符串
- 方法1(需要头文件<sstream>)
int a = 1234;
stringstream ss;
string out;
ss << a;
ss >> out;
cout << out << endl;
- 方法2(C++ 11 新标准)
int a = 1234;
cout << to_string(a) << endl;
5.queue
5.1.queue构造
queue<int> q;
5.2.push/back/front/size
q.push(5);
q.push(6);
cout << q.front() << endl; // 5
q.pop();
cout << q.front() << endl; // 6
cout << q.size() << endl; // 1
6.map/unordered_map
6.1map
map<int, int> m;
// map的底层是一个树形结构,所以map会有序,顺序是按照第一个即2 3 6来排
m[3] = 5;
m[2] = 10;
m[6] = 1;
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;
/*
2 10
3 5
6 1
*/
- 查找map中的元素
int occurs=0;
map<string,int>::iterator it = m1.find("foobar");
if(it != word_count.end())
occurs = it->second;
6.2.unorder_map
unordered_map<int, int> m;
// unordered_map的底层是一个哈希结构,无序,but使用起来会快很多
m[3] = 5;
m[2] = 10;
m[6] = 1;
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;
6.3.排序
bool cmp(pair<int, int> a, pair<int, int> b)
{
return a.first > b.first;
}
int main()
{
unordered_map<int, int> m;
m[3] = 5;
m[2] = 10;
m[6] = 1;
/*
sort(m.begin(), m.end(), cmp); 这里map不可排序导致程序出错
for (auto tmp : m)
cout << tmp.first << " " << tmp.second << endl;
*/
// 转化成vector进行排序
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;
}
7.set/unordered_set
set是一个集合,不能有重复元素,所以不论用insert插入几次4,都只有一个元素
set<int> s; // 树状结构 有序
unordered_set<int> s2; // 哈希结构 无序 快
s.insert(3);
s.insert(4);
s.insert(4);
s.insert(4);
cout << s.size() << endl; // 2
for (auto tmp : s)
cout << tmp << " ";
cout << endl;
// 3 4
for (auto it = s.begin(); it != s.end(); it++)
cout << *it << " ";
// 3 4
cout << endl;
8.deque
8.1.构造
deque<int> d
8.2.push/pop/end/…
deque和其他相比更加灵活,但是出现的少
deque<int> d;
d.push_back(2);
d.push_back(4);
d.push_front(5);
d.push_front(10);
for (auto tmp : d)
cout << tmp << " ";
cout << endl;
d.pop_front();
d.pop_back();
for (auto it = d.begin(); it != d.end(); it++)
cout << *it << " ";
/*
10 5 2 4
5 2
*/
8.3.排序(algorithm)
sort(d.begin(), d.end(), less<int>());//默认,从小到大
sort(d.begin(), d.end(), greater<int>());
9.list
9.1.构造
list<int> li
9.2.push/emplace/insert/pop_back…
list<int> li;
li.push_back(2);
li.push_front(4);
li.emplace_back(10);
li.emplace_front(5);
for (auto it = li.begin(); it != li.end(); it++) cout << *it << " "; // 5 4 2 10
cout << endl;
li.insert(++li.begin(), 1); // 用了++可以把1放到第一个数的后面变成第二个
li.pop_back();
for (auto x : li) cout << x << " "; // 5 1 4 2