STL 常用方法
1. 选择 C++ 刷算法的理由
- 1、C++ 速度快(C 不是更快吗,Java 太慢了)
- 2、C++ 有 STL(什么是 STL)——性能强大,使用方便的标准库
- 3、如何使用 STL 进行高效刷算法
- 4、好处:刷算法,学习成本低
- 5、如何从 C 到 C++(仅基础语法到刷算法程度)
俗话说:磨刀不误砍柴工,不会 C++ 仍然可以刷算法,但是效率相对很低。在 ACM 或各类程序算法竞赛中相比于 Java 代码的冗长,C 的繁琐,Python 的性能低下,C++ 以兼顾简洁和高效脱颖而出。
2. 输入输出
C++ 保留了 C 的 scanf 和 printf,额外增加了 cin 和 cout。
Example:
2.1 C 程序中的输入输出
int a; scanf("%d", &a); printf("%d", a);
2.2 C++ 程序中的输入输出
int a; cin >> a; cout << a;
2.3 C++ 程序中的连续输入输出
int a, b, c; cin >> a >> b >> c; cout << a << b << c;
2.4 C++ 优雅地换行
cout << 1; cout << endl; cout << 2; cout << 3 << endl << endl;
Notice: cin、cout 使用虽然很方便,但是比 scanf、printf 效率慢太多,算法竞赛中常常会因为使用了 cin、cout 而导致 TLE 等情况,在输入输出的数据量(> 1000)甚至更多的时候,使用 scanf、printf 代替 cin、out 通常是一种更好的选择。
3. STL 与 algorithm 头文件
STL 是“容器”的集合,这些“容器”中常见的有 list, vector, set, map等,STL 同时也是算法和其他一些组件的集合。
algorithm 是对容器继承的一些算法函数,可以更方便高效的编写程序,例如 sort 函数。
概念: 迭代器可以理解为指针。
#include<vector> #include<iostream> #include<algorithm> using namespace std; int main() { vector<int> arr{1, 9, 2, 8, 3, 7, 4, 6, 5}; // 列表初始化 sort(arr.begin(), arr.end()); for(vector<int>::iterator it = arr.begin(); it != arr.end(); it++){ cout << *it << endl; // 使用 * 访问迭代器指向的元素 } return 0; }
有关迭代器的具体应用我会在另外一篇博文中详细说明。
4. STL の string
概念:相当于 char* 的封装,理解为字符串
4.1 简单使用
/**C中定义字符串以及打印*/ char *ch="asdkajbf"; for(int i=0;ch[i]!='\0';i++) cout<<*(ch+i); /**C++中*/ string s="ssadaffw"; cout<<s<<endl;
4.2 如何获取一行字符串
我想获取一行字符串
hello world
C 中:
scanf("%s",ch);//1.仅获取一个单词,空格结束 2.ch[100]得设置初始大小
C++中:
string s; getline(cin,s);//获取一行数据 cout<<s;
4.3 += 运算符
+= 对于字符串,字符有效,数字会转为 ASCII 码
string s; s+="hello"; s+=" world"; cout << "s0: " << s << endl; s+='5'; cout << "s1: " << s << endl; s+=10; //10对应的asc码是换行 cout << "s2: " << s << endl; int a=5; //想把a加入字符串 s+=(a+'0'); cout<< "s3: " << s << endl;
4.4 排序(使用algorithm)
string s="5418340"; sort(s.begin(),s.end()); cout<<s;
4.5 erase 函数
/**begin是头迭代器,end是尾迭代器*/ string s="5418340"; s.erase(s.begin());//删除第一个 s.erase(--s.end());//删除最后一个 cout<<s;
4.6 substr 函数
/**begin是头迭代器,end是尾迭代器*/ string s="5418340"; s=s.substr(1,3);//取418,取索引为1,往后截断3个 s=s.substr(1,-1);//索引为1,截断到最后 cout<<s;
4.7 循环(3种)
1.for循环
string s = "5418340"; for(int i = 0; i < s.length(); i++) cout<<s[i];
2.迭代器
for(string::iterator it=s.begin();it!=s.end();it++) cout << *it;
3.迭代器化简
for(auto it=s.begin();it!=s.end();it++) cout << *it;
4.利用 C++11 新特性 for 循环
for(auto x:s) cout<<x;
5. STL vector
概念:vector相当于数组,模板类型相当于存放的内容
5.1 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 for(auto x:v3) cout<<x;
5.2 用 at 或者 [] 获取元素
vector<int> v{1,2,3,4,5}; cout<<v[1];//取索引为1的 cout<<v.at(2);//取索引为2的
5.3 方法
// push_back追加内容 vector<int> v; v.push_back(5); v.push_back(5); v.push_back(5); v.push_back(5); v.push_back(6); for(auto x:v) cout<<x; // resize进行重置大小 v.resize(10); //不赋值默认为0 // erase 删除元素,复杂度为O(n) v.erase(v.begin()); //删除第一个元素 v.erase(--v.end()); //删除最后一个元素 // 获取第一个元素,获取最后一个元素 /**获取第一个元素*/ cout << v.front(); cout << v[0]; cout << *v.begin(); /**获取最后一个元素*/ cout << v.back(); cout << v[v.size()-1]; //size是获取大小 cout << *--v.end();
5.4 排序
第三个参数为比较器,不写默认为 less()
vector<int> v{5,1,2,5,4,0,-1}; sort(v.begin(),v.end(),less<int>());//从小到大 sort(v.begin(),v.end(),greater<int>());//从大到小排序 for(auto x:v) cout<<x;
5.5 循环
vector<int> v{5,1,2,5,4,0,-1}; for(int i=0; i<v.size(); i++) cout<<v[i]; //for循环 cout<<endl; for(vector<int>::iterator it=v.begin();it!=v.end();it++) cout<<*it; //迭代器循环 cout<<endl; for(auto it=v.begin();it!=v.end();it++) cout<<*it; //迭代器简化循环 cout<<endl; for(auto x:v) cout<<x;//c++11新特性
6. STL の stack
概念:栈
构造
stack<int> s;
- push、pop、size、empty
- push 入栈一个元素
- pop 出栈一个元素,pop无返回值
- top 取栈顶元素
- size 查看元素个数
s.push(2); s.push(3); cout<<s.top()<<endl; s.pop(); cout<<s.top()<<endl; cout<<s.size()<<endl;
进制转换(十进制转二进制)
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; }
逆序单词(拓展 sstream,stoi,itoa)
输入一行字符串,将字符串逆序打印
输入:
hello world my name is steve yu
输出:
yu steve is name my world hello
#include <iostream> #include <stack> #include <sstream> using namespace std; int main(){ string str; stack<string> 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<<" "; } return 0; }
字符串转数字
Solution 1:
string s="1234"; int i; stringstream ss; ss<<s; ss>>i; cout<<i;
Solution 2:
string s="1234"; int i=stoi(s); cout<<i;
数字转字符串
Solution 1:
int a=1234; string out; stringstream ss; ss<<a; ss>>out; cout<<out<<endl;
Solution 2(c++ 11)
int a=1234; cout<<to_string(a)<<endl;
7. STL の queue
概念:队列
构造
queue<int> q; push、back q.push(5); q.push(6); cout<<q.front()<<endl; q.pop(); cout<<q.front()<<endl; cout<<q.size()<<endl;
8. STL の map(unordered_map pair)
概念:映射(map 为树状表,unorderedmap 为哈希表)
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 的用法(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]=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; }
9. 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;
10. STL の 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>());
11. STL の 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;
12. 文档
(英文:)[http://www.cplusplus.com/reference/stl/]
(中文:)[http://c.biancheng.net/stl/map/]