C++

关于编译器

  • gcc 主要用作 C 语言编译器,但它实际上可以编译多种语言的代码,包括 C、C++等
  • g++ 专门用于编译 C++ 代码

在使用gcc编译时,需要添加-lstdc++ -o-lstdc++ 选项用于告诉编译器链接 C++ 标准库,-o 选项指定输出文件的名称。

而在使用g++时,则无需,但要在JSON文件里修改编译器(许多软件、工具、框架都使用 JSON 作为配置文件格式)

代码

1
using namespace std;

需要避免与用户自定义的类或函数名字与 C++ 标准库 大量常用的工具和数据结构(例如 vectorstringmap 等)冲突。为了避免每次都写 std:: 前缀在前面声明这样一句话。

for

常见的几种使用方式:

  • 传统的循环方式,for(int i = 0;;),如果是循环中初始化的变量,作用域只能在for循环里。
  • 遍历容器或数组,for (declaration : container)
  • 使用引用的范围,for (int& num : numbers)
    • 这里的&表示引用,当函数参数是大对象时,使用值传递会导致对象被复制,消耗大量的内存和性能。通过使用按引用传递,可以避免复制,只传递对象的引用。与指针有很大的区别,比如指针可以是空的,但引用必须在初始化的时候就指向某个对象,等。当被引用的对象不能进行更改时,可以用const进行修饰。,此外该符号还有取地址的意思。

字符串

  • 判断两个字符串是否相同的方式
    • 运算符==
    • 方法std::string::compare(),返回0表示字符串相等
    • 函数std::strcmp(),返回0表示字符串相等
    • 函数boost::iequals(),比较时忽略大小写
  • insert可用于给哈希表添加元素,push_back用于动态的(数组vector、不能用于哈希表)插入元素

复杂度

  • 时间复杂度,可以理解为在最坏情况下,程序中某个操作(例如循环或递归)执行的次数。大 O 表示法的规则,我们忽略常数因子。
  • 空间复杂度,算法执行过程中需要额外的存储空间,比如循环中迭代的i复杂度就是O(n),不管输入或常量规模多大,复杂度都是O(1)。

哈希表

unordered_set只储存键, 官方库不支持<vector>类型 ,使用.insert()函数进行插入,unordered_map即储存键也储存值,只插入键时,默认的值是0,不能只插入键,必须插入键值。比如map1[p[i]] = 0;。当元素不在容器中时,.find()会返回.end().erase()用于删除哈希表的某个键。.clear()用于清空所有键。_对于一般的数据类型都是有官方的哈希函数的,但是如果是数组则需要自己定义,比如vector<int>或者vector<char>_。

常见用途:

  • 快速查找
  • 去重
  • 计数
  • 快速判断元素是否存在

将哈希表中的键存入数组:

1
2
3
for (const auto& key : keys) {  //&表示引用,相当于直接操作要被遍历的变量,减少了地址的开销
cout << key << " ";
}

双指针

  1. 快慢指针
  2. 左右指针

作用主要在于降低时间复杂度,比如在处理三数之和的数组时…

排序

C++标准库有可以直接使用的排序函数,sort(数组的开始位置,数组结束的位置),默认是升序排序,降序如下:

1
2
3
4
5
6
//升序
sort(nums.begin(), nums.end());//对nums进行排序
// 使用 lambda 表达式进行降序排序
sort(vec.begin(), vec.end(), [](int a, int b) {
return a > b; // 如果 a > b,则返回 true,表示降序
});