开篇词
# C++语法精粹:解算法题的语法工具
在本章节,我们将深入探讨那些在算法竞赛和互联网公司算法笔面试中所必需的核心C++语法。我们的目标是帮助你构建一个针对性强、高效精简的C++语法工具集,以便你能够迅速地迈入算法的大门。
我们将重点介绍以下关键语法元素:
- 输入输出流:掌握如何快速便捷地读取和输出各种类型的数据,这是算法实现的基础。
- 核心概念:变量类型、存储方式、作用域、函数定义与调用等。
- 逻辑控制:判断、循环、break、continue关键字等。
- 标准模板库(STL):系统整理STL中各类容器以及算法的常见用法。
同时会介绍与算法笔面试高度相关的典型OJ特点及使用方式,错误类型,评测机时间空间限制等必要概念。
重要提示
C++语言特性非常丰富且庞大,但在算法学习中,我们希望更快接触到算法思想。因此,本章不会涉及那些对于算法解题非必要的高级语法特性,如模板编程和并发编程。
尽管如此,语法学习中所涉及到的计算机原理,文章中会深入分析和讲解,如计算机中数的表示,存储空间等等。
我们的目标是让你掌握解算法题所需要的核心语法,快速推开算法的大门,专注于对算法逻辑的构建和优化,从而在算法竞赛和面试中脱颖而出。通过本章的学习,你将掌握一套定制于解算法题的既实用又高效的C++语法工具集,为你的算法之旅打下基础。
# 算法与工程的区别
举几个小例子
# 算法题不需要太考虑语言特性
// OI,ACM风格:笔试题可以写这个,以快速通过题目为目的
vector<int> v{1, 2, 3};
for (int p : v) {
cout << p << endl;
}
2
3
4
5
// 工程风格:面试可以写这个,体现对语言特性的理解
vector<int> v{1, 2, 3};
for (const int &p : v) { // const和这里的引用符号&,其实都是语言特性层面的东西。
cout << p << endl;
}
2
3
4
5
Tips
如果你是初学者,那么完全可以先学会第一种写法去应试。
从解算法题的角度,两种写法在时间复杂度层面不会有数量级上的差异,都能够正确通过评测。
第二种写法效率上确实会更高一些,使用了const和引用的特性。如果你熟悉C++,并且写过C++工程,那么就直接写第二种。
# 算法题空间不超限即可
定义一个二维数组,你可能会看到如下两种写法:
vector<vector<int>> matrix(n, vector<int>(m)); // 写法1:工程
int matrix[n][m]; // 写法2:解题,OI,ACM风格
2
我们在力扣上,是不是经常见到第一种写法,对于初学者来说,是不是有一丢丢难背?
如果题目中我们需要开二维数组,那么可以采用下面这种写法:
const int N = 25;
const int M = 100005;
int matrix[N][M];
2
3
疑问
你开一个这么大的数组,万一测试样例的
那我要说,竞赛题,笔试题,一般都是限制256MB空间,所以在不超限制的情况下,肯定要快速实现,方便记忆的做法咯。
当然如果你是熟悉C++工程,那肯定还是写法1,开动态数组,更符合工程规范,空间利用也更加高效。
面试中怎么写?
如果你面试的是大厂C++岗(QT,基础架构,音视频)等,面试时还是可以做一些工程化的实现,给面试官体现对语言特性的了解。
如果题目侧重算法(考思想),则可以写OI,ACM风格,快速A题(指题目被accept)。
如果题目侧重工程(实现线程调度之类的),那么你需要实现语言特性,遵循工程规范。
如果你面试的是量化、车企等C++岗位,那么考工程C++的概率更大。
总之,考工程题,就需要在本章提供的应试做法之上,学习一下工程规范了。(笔者算法专栏写完,这部分也会更新为一个板块)
# 总结
可以很负责任地说,看看OIer or ACMer的代码,会发现很多并不符合工程规范的东西,因为这是对应试而做出的精简与改造。
如上的例子还有很多,有很多为应试而做出的努力,会在后面的文章中不断体现。
C++的初学者,通过阅读本章的内容,能快速掌握解算法题所需要的核心语法,踏入算法的大门,而不是看着力扣题解,望而生畏,无从下手。
学习之道,犹如登高必自卑,循序渐进方显真章。探索算法之海,当以洞察其核心思想为先,勿让C++之繁复语法,如迷雾般遮蔽了前行的视线。