闲杂
1 |
|
花括号与分号
在结构体与类定义大括号后面需要分号;
其余可要可不要
if else、try catch等组合语句如果在中间加了分号会将一个语句块分成两个
cmath
1 | #include <cmath> |
数组
对于内置数据类型元素的数组,必须使用()来显示指定程序执行初始化操作,否则程序不执行初始化操作:
1 | int *pia = new int[10]; // 每个元素都没有初始化 |
类类型元素的数组,则无论是否使用(),都会自动调用其默认构造函数来初始化:
1 | string *psa = new string[10]; // 每个元素调用默认构造函数初始化 |
std::find()
返回范围 [first, last) 中满足特定判别标准的首个元素迭代器,查找失败则返回end迭代器
std::sort()
1 | // 自定义函数必须写在最外吗,否则无法通过 |
lamda 表达式:1
2
3std::sort(s.begin(), s.end(), [](int a, int b) {
return b < a;
});
重载operator()
运算符1
2
3
4
5
6
7struct {
bool operator()(int a, int b) const
{
return a < b;
}
} customLess;
std::sort(s.begin(), s.end(), customLess); //升序
std::reverse()
反转[first, last)范围中的元素顺序. (借助 std::swap()
实现)1
2
3std::vector<int> v{1,2,3};
std::reverse(std::begin(v), std::end(v));
std::reverse(v.begin(), v.end());
vector
常用操作
截取vector中的一部分作为一个新的vector1
2
清空:clear()
在最后添加元素:push_back()
初始化1
2
3vector<string> v3(5, "hello"); // 创建有5个值为“hello”的string类对象的容器
std::vector<int> v = {7, 5, 16, 8};
判断某元素是否存在1
2
3
vector<string> vStr;
int nRet = std::count(vStr.begin(), vStr.end(), "abc");//返回向量中,“abc”元素的个数
at:访问指定字符,有边界检查 str.at(1)
front:访问首字符 (C++11) str.front()
back:访问最后的字符(C++11)Cpp
string类
常用操作
截取子串
s.substr(pos, n) 截取s中从pos开始(包括0)的n个字符的子串,并返回
s.substr(pos) 截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
替换子串
s.replace(pos, n, s1) 用s1替换s中从pos开始(包括0)的n个字符的子串
查找子串
s.find(s1) 查找s中第一次出现s1的位置,并返回(包括0)
s.rfind(s1) 查找s中最后次出现s1的位置,并返回(包括0)
s.find_first_of(s1) 查找在s1中任意一个字符在s中第一次出现的位置,并返回(包括0)
s.find_last_of(s1) 查找在s1中任意一个字符在s中最后一次出现的位置,并返回(包括0)
s.fin_first_not_of(s1) 查找s中第一个不属于s1中的字符的位置,并返回(包括0)
s.fin_last_not_of(s1) 查找s中最后一个不属于s1中的字符的位置,并返回(包括0)
判断字符串string里面是否含有某个字符串
利用string::size_type string::find(string &);
函数
1 |
|
c++字符串比较大小的两种方法
- compare函数的使用:
1 |
|
- 使用strcmp(aa1.c_str(),bb2.c_str())
1 |
|
统计字符串中某个字符出现了多少次
使用算法库里面的count函数,使用方法是count(begin,end,‘a’),其中begin指的是起始地址,end指的是结束地址,第三个参数指的是需要查找的字符
1 |
|
元素访问
at:访问指定字符,有边界检查 str.at(1)
front:访问首字符 (C++11) str.front()
back:访问最后的字符(C++11)Cpp
c_str:返回不可修改的C字符数组版本(带’\0’) str.c_str()
交换string的值
成员函数: string::swap(string& str)
主要用于交换两个string的值,用法如下:
1 |
|
非成员函数std::swap()
可以将string内部的两个元素进行交互。同时,也可以对两个string进行交换
1 |
|
vector
连续存储结果, 每个元素在内存上是连续的, 支持 高效的随机访问和尾端插入/删除操作, 但其他位置的插入/删除操作效率低下, 可以看做是一个数组, 但是与数组的区别为: 内存空间的扩展. vector 支持动态大小的数据存储, 而数组则必须指定大小, 但需要扩展空间时, 需要手动实现.
vector的内存分配原理及实现:
在STL内部实现时, 首先分配一个较大的内存空间预备存储, 即capacity()
函数返回的大小, 当超过此分配的空间时, 会再重新分配一块更大的内存空间(VS6.0是两倍, VS2005是1.5倍). 通常默认的内存分配能完成大部分情况下的存储操作. 扩展空间的步骤:
- 配置一块新空间
- 将就元素一一移动到新地址中
- 把原来的空间释放掉
vector的数据安排以及操作方式, 与数组模板Array十分相似, 两者唯一的差别在于空间利用的灵活性, Array的空间扩展需要手动实现
deque
双端队列: double-end queue
连续存储结果, 即每个元素在内存上是连续的, 类似于vector, 不同之处在于, deque提供了两级数组结构, 第一级完全类似于vector, 代表实际容器, 另一级维护容器的首位地址, 这样, deque除了具有vector的所有功能之外, 还支持高校的首/尾端的插入/删除操作.
优点:
- 随机访问方便, 支持
[]
操作符和.at()
访问函数 - 可在两端进行push, pop操作
缺点:
占用内存多
list
非连续存储结构, 具有两链表结构, 每个元素维护一对前向和后向指针, 因此支持前向/后向遍历. 支持高效的随机插入/删除操作, 但是随机访问效率低下, 且由于需要额外维护指针, 开销也比较大. 每一个节点都包括一个信息块info, 一个前驱指针Pre, 一个后驱指针Post.
优先:
- 不使用连续内存完成插入和删除操作
- 在内部方便的进行插入和删除操作
- 可以在两端push, pop
缺点:
- 不能进行随机访问, 即不支持
[]
操作符和.at()
访问函数 - 相对于vector占用内存多
list与vector的区别
- vector为存储的对象分配一块连续的地址空间, 随机访问效率很高. 但是插入和删除需要移动大量的数据, 效率较低. 尤其当vector内部元素较复杂, 需要调用复制构造函数时, 效率更低.
- list中的对象是离散的, 随机访问需要遍历整个链表, 访问效率比vector低, 但是在list中插入元素, 尤其在首尾插入时, 效率很高.
- vector 是 单向的 的, 而 list 是双向的 (vector为什么单向???)
- vector 中的 iterator 在使用后就释放了, 但是 list 不同, 它的迭代器在使用后还可以继续使用, 是链表所特有的.
queue
deque
map
1、map简介
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。
对于迭代器来说,可以修改实值,而不能修改key。
2、map的功能
- 自动建立Key - value的对应。key 和 value可以是任意你需要的类型。
- 根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。
- 快速插入Key -Value 记录。
- 快速删除记录
- 根据Key 修改value记录。
- 遍历所有记录。
-3. 使用map
1 |
4. map的构造函数
map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:1
map<int, string> mapStudent;
5. 数据的插入
unordered_map
与map
的区别
在STL中, map
对应的数据结构是红黑树, 红黑树是一种近似于平衡的二叉查找树, 里面的数据是有序的, 在红黑树上做查找的时间为 $O(lonN)$. 而unordered_map
对应哈希表, 哈希表的特点就是查找效率高, 时间复杂度基本为 $O(1)$, 而额外空间复杂度较高.
基本使用
1 |
|
set
基于红黑树实现
unordered_set
基于哈希表实现, 会将传入的值处理成相应的键值, 该键值对应着一个特定的位置, 因此, unordered_set
的各项操作的复杂度平均为常数级(最差为线性), 同时, unordered_set
也是一种 set
, 因此, 其关键字不能有重复(重复的会自动合并).
1 | unordered_set<string> stringSet; |
优先级
&
|
的优先级较低, 通常情况下需要使用括号括起来.
三元运算符 ?:
的优先级也很低, 当其进行算数运算时, 也建议使用括号括起来.