输入输出
C++保留了C的scanf和printf,增加了额外的cin与cout
例子
C程序中输入输出
1 | int a; |
C++输入输出
1 | int a; |
连续输入输出变量
1 | int a,b,c; |
优雅地换行
1 | cout<<1; |
好处:
1.少写了很多东西
2.连续输入输出变量
3.换行优雅
注意:cin、cout比scanf、printf慢,有时候刷算法超时,可能因为使用了cin、cout 输入输出的数量(>1000)特别多,刷算法用cin,cout容易超时
STL(Standard Template Library)与algorithm头文件
STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。
algorithm是对容器继承的一些算法函数,辅助刷算法题
概念:迭代器——理解为指针
1 |
|
string
概念:相当于char*的封装,理解为字符串
简单使用
1 | /**C中定义字符串以及打印*/ |
获取一行字符串
我想获取一行字符串
1 | hello world |
C中:
1 | scanf("%s",ch);//1.仅获取一个单词,空格结束 2.ch[100]得设置初始大小 |
字符转字符串
string构造方法
char c = 'A'; string s(1, c);
push_back
string s; s.push_back(c);
+=
char c = 'A'; string s; s += c;
C++中:
1 | string s; |
字符串转数字atoi
std::string str = "123";
int n = atoi(str.c_str());
cout<<n; //123
+=运算符
+=对于字符串,字符有效,数字会转为asc码
1 | string s; |
排序(使用algorithm)
1 | string s="5418340"; |
erase函数
1 | /**begin是头迭代器,end是尾迭代器*/ |
substr子串函数
1 | /**begin是头迭代器,end是尾迭代器*/ |
reverse翻转函数
1 | string str = "abcdefghijk"; |
在某些情况下,可能要手写reverse函数:
1 | void reverse(string &str, string::iterator start, string::iterator end) { |
1 | void reverse(string &str) { |
sort函数
1 | string str = "akjkkskkskbc0"; |
子串查找find
string的find()函数用于找出字母在字符串中的位置。
find(str,position)
find()的两个参数:可以不填第二个参数,默认从字符串的开头进行查找。
str:是要找的元素
position:字符串中的某个位置,表示从从这个位置开始的字符串中找指定元素。
- 返回值为目标字符的位置,当没有找到目标字符时返回npos。
string::npos其实就是-1
例1:找到目标字符的位置
1 | string s = "hello world!"; |
例2:未找到目标字符
1 | string s = "hello world!"; |
例3:指定查找位置
1 | string s = "hello world!"; |
从空格开始(包含空格)的后半部分字符串中寻找字符”l”,结果找到了world中的”l”在整个字符串中的位置
例4:找到目标字符在字符串中第一次出现和最后一次出现的位置
1 | string s = "hello world!"; |
例5:反向查找:
1 | string s = "hello world!"; |
to_string()
函数原型:
string to_string (int val);
string to_string (long val);
string to_string (long long v****al);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
功能:
将数值转化为字符串。返回对应的字符串。
字符串遍历(4种)
- for循环
1 | string s="5418340"; |
- 迭代器
1 | for(string::iterator it=s.begin();it!=s.end();it++) cout<<*it; |
- 迭代器化简
1 | for(auto it=s.begin();it!=s.end();it++) cout<<*it; |
- 利用C++ 11新特性for循环
1 | for(auto x:s) cout<<x; |
vector
概念:vector相当于数组,模板类型相当于存放的内容
vector构造
1 | //定义一个空vector |
用at或者[]获取元素
1 | vector<int> v{1,2,3,4,5}; |
常用方法
- push_back追加内容
1 | vector<int> v; |
- resize进行重置大小
1 | v.resize(10);//不赋值默认为0 |
- erase删除元素,复杂度为O(n)
1 | v.erase(v.begin());//删除第一个元素 |
- 获取第一个元素,获取最后一个元素
1 | /**获取第一个元素*/ |
- 插入元素
1 | vector<int> vec; |
排序
第三个参数为比较器,不写默认为less< int >(), 即从小到大排序
1 | vector<int> v{5,1,2,5,4,0,-1}; |
遍历
1 | //1.for循环遍历 |
stack
概念:栈
构造
1 | stack<int> s; |
常用方法
- push()、pop()、size()、empty()
- push() 入栈一个元素
- pop() 出栈一个元素,pop()无返回值
- top() 取栈顶元素
- size() 查看元素个数
- empty()查询是否为空
1 | s.push(2); |
进制转换(十进制转二进制)
1 | int itob(int decimal){ |
逆序单词(拓展sstream,stoi,itoa)
输入一行字符串,将字符串逆序打印
输入:hello world my name is steve yu
输出:yu steve is name my world hello
1 |
|
字符串转数字
- 方法1:
1 | string s="1234"; |
- 方法2:
1 | string s="1234"; |
数字转字符串
- 方法1:
1 | int a=1234; |
- 方法2:(c++ 11)
1 | int a=1234; |
queue
队列是一种FIFO的线性数据结构。使用时要#include
构造
1 | queue<int> q; |
常见方法
- push():从队尾进队列
- pop():从队头出队列
- front():获取队头元素
- back():获取队尾元素
- size():获取队列元素个数
1 | q.push(5); |
priority_queue
概念:优先级队列
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。
首先要包含头文件#include
优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。优先队列可以以O(log n) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质来决定的。
和队列基本操作相同:
- top() 访问队头元素
- empty() 队列是否为空
- size() 返回队列内元素个数
- push() 插入元素到队尾 (并排序)
- emplace() 原地构造一个元素并插入队列
- pop() 弹出队头元素
- swap() 交换内容
优先级队列默认大顶堆,即元素从大到小排列。
初始化
priority_queue< Type, Container, Functional >
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式。当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆,即降序队列。
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,大顶堆,默认
priority_queue <int,vector<int>,less<int> >q;
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
更为复杂的比较规则参考这里
priority_queue
默认初始化方式, 默认情况下,最大堆,元素从大到小排列 srand(time(NULL)); priority_queue<int> q; for(int i=0;i<10;i++){ int num=rand()%10; q.push(num); } while(!q.empty()){ count<<q.top()<<" "; q.pop(); }
priority_queue
, greater > q; 这种初始化方式是最小堆,元素从小到大排列。
自定义比较方法
bool myCmp(int a, int b){ return a%10 < b%10; } priority_queue<int, vector<int>, function<bool(int, int)>> q(myCmp);
这种初始化方式是按照个位数从大到小排列。
deque
双端队列是一种特殊的队列,用特殊的数据结构实现了在头尾都可进、出队列。
常见方法
- push_back():从队尾进队列
- pop_back():从队尾出队列
- push_front():从队头进队列
- pop_front():从队头出队列
- front():获取对头元素
- back():获取队尾元素
- size():获取队列元素个数
1 | deque<int> d; |
map
映射(map为树状表,unorderedmap为哈希表)。使用时要#include
初始化
1 | //自动初始化 |
常见方法
- 插入
1 | // insert pair |
- 查找
find():使用find,返回的是被查找元素的位置,没有则返回map.end()
1 | if (hashMap.find(11)!=hashMap.end()) { |
count(key):使用count,返回的是被查找元素的个数。如果有,返回1;否则,返回0。注意,map中不存在相同元素,所以返回值只能是1或0。
1 | if (hashMap.count(11)!=0) { |
- 删除
1 | // delete by iterator |
- 遍历/倒序遍历
1 | map<int,int> m;//有序的,树状结构(底层) |
map转成vector进行排序
1 | bool cmp(pair<int,int> a,pair<int,int> b){ |
unordered_map
unordered_map是哈希结构实现的map, 查找、插入的时间复杂度都是O(1)
1 | unordered_map<int,int> m; |
set
基于树状结构实现,集合内元素有序且不包含重复元素。
常用方法
- insert()
- sort()
- size()
- empty()
1 | set<int> s; |
- 查找find() 和 count()
1 | set.find(item)!=set.end() //item存在于set中 |
- 删除erase()
1 | set<int>::iterator p = set.find(item); |
unordered_set
基于哈希结构实现,集合内元素无序,查找O(1)
list
双向链表
1 | list<int> li; |
文档
英文:
http://www.cplusplus.com/reference/stl/
中文: