C++

c++ 容器及算法

Posted by infinityyf on March 2, 2020

容器

set

有序存储数据,并且每个数据都是独一无二的存在。使用比较函数compare进行比较排序。常用红黑树实现。

成员方法

方法名 功能
clear 清空内容
erase 擦除内容
swap 交换数据
count 返回匹配特定键的元素数量
find 寻找带有特定键的元素

unordered_map / unordered_set

哈希映射和哈希集合,以空间换时间的快速查找容器
unordered_map
| 方法名 | 功能 | | :—— | :—— |
|insert|插入map元素| |erase|删去| |size|队列元素个数| |emplace|创建一个元素并插入| |swap|交换两个元素| |at|索引查询| |find|使用key查找| |contains|是否包含key|

priority_queue

优先队列,具有最高优先级的元素先出。通过堆进行实现
| 方法名 | 功能 | | :—— | :—— |
|top|访问队头元素| |empty|队列是否为空| |size|队列元素个数| |push|插入队列中,并排序| |emplace|创建一个元素并插入| |pop|弹出队头元素| |swap|交换两个元素|

例子

//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;

vector

向量
| 方法名 | 功能 | | :—— | :—— |
|clear|清空内容| |empty|向量是否为空| |size|向量元素个数| |push_back|插入向量末尾| |pop_back|弹出末尾元素| |emplace|创建一个元素并插入| |resize|改变容器中可存储的元素个数| |swap|交换两个元素| |erase|擦除指定元素,可以指定位置和范围,擦除后size改变| |insert|插入,用法比较多,可插入值,可插入多个值,可插入范围|

算法

make_heap, pop_heap,

make_heap: 构造堆结构 pop_heap: 将堆顶放置在最后,并将剩余的数据的最大值放在堆顶 push_heap: 将新的数据方入容器之后,使用该方法插入堆中正确位置

reverse

反转一个范围内的序列

sort

排序,sort支持的排序一定是 strict weak ordering,即comp(a,a)==false

partition

会将区间[first,last)中的元素重新排列,满足判断条件pred的元素会被放在区间的前段,不满足pred的元素会被放在区间的后段。该算法不能保证元素的初始相对位置,如果需要保证初始相对位置,应该使用stable_partition.

iterator

这里主要说一下使用erase函数删除迭代器指向的元素。

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )//这里不能++
{
     if( *iter == 3)
          iter = veci.erase(iter);  //需要设置到erase元素的后一个原色
      else
            iter ++ ;
}

字符串

元素访问方法
| 方法名 | 功能 | | :—— | :—— |
|at|访问指定字符,并进行边界检测,以索引为参数| |front|访问首字符| |back|返回最后字符| |data|返回首字符的指针| |c_str|转换为c风格字符串|

容量相关
| 方法名 | 功能 | | :—— | :—— |
|empty|是否为空| |size/length|返回字符数| |max_size|返回字符数最大数| |capacity|存储字符的容量| |shrink_to_fit|释放不必要的内存|

操作
| 方法名 | 功能 | | :—— | :—— |
|clear|清除内容| |insert|插入字符| |erase|移除字符| |push_back/pop_back|末尾修改| |append|末尾添加,可以是一个串| |starts_with/ends_with|是否以指定字符开始或结束| |replace|替换指定部分| |substr|获得字串| |resize|更改存储的字符数| |swap|交换内容|

查找
| 方法名 | 功能 | | :—— | :—— |
|find|查找字符或字串| |find_first_of|字符首次出现| |find_first_not_of|字符首次缺失|

随机数

通过随机数种子生成随机数,通过random_device定义一个随机数种子,不用显示计算。种子生成示例:

#include <random>                                // For random_device class
#include <iostream>                              // For standard streams
int main()
{
    std::random_device rd;                         // A function object for generating seeds
    for(size_t n {}; n < 8; ++n)
        std::cout << rd() << " ";
    std::cout << std::endl;
}

获得种子之后使用随机数生成器进行随机数的生成,默认生成器为default_random_engine

常用的随机数分布

uniform_int_distribution 整数均匀分布 uniform_real_distribution 实数均匀分布
normal_distribution 正态分布 使用示例

std::uniform_real_distribution<> values {0.0, 10.0};//上下限
std::random_device rd; // Non-de terrains tic seed source
std::default_random_engine rng {rd()}; // Create random number generator for(size_t i {}; i<8; ++i)
std::cout << std::fixed << std::setprecision(2)<< values (rng) <<" ";

补充内容

经常在使用头文件的时候出现xxx已经在.obj中定义,或xxx无法解析。这是因为常常我们在h文件中定义变量,在cpp中使用,但是头文件常常被不同cpp引用,这样的话就相当于每一次都定义了那些h文件中的变量。

为了解决这个问题,需要在h文件中声明变量,并在变量前加上extern,在使用的cpp中对该变量进行定义。如果不定义,则就会出现xxx无法解析的现象

迭代器萃取

iterator_traits,是迭代器类型的接口,仅针对迭代器实现算法。

  1. difference_type - 可用来标识迭代器间距离的有符号整数类型
  2. value_type - 迭代器解除引用后所得到的值的类型。对于输出迭代器,该类型为 void 。
  3. pointer - 指向被迭代类型 (value_type) 的指针
  4. reference - 被迭代类型 (value_type) 的引用类型
  5. iterator_category - 迭代器类别。必须是迭代器类别标签之一,这个类型存在继承和嵌套关系