跳转至

数组申请

由于你写的单文件代码是为了处理一件事,并且处理完就退出,那么一些工程上的规范实际上是不需要遵守的。1 这里我们讲一些在算法题里常见的实践。

全局数组

你可以放心大胆使用全局数组。全局数组通常指的是开在函数外面、大小是常数的数组,默认会在程序开始被初始化为默认构造函数(通常为 \(0\) 或者空容器)。

为了减轻思想负担,你可以考虑粗略计算需要的数组大小,多开一点,避免使用类似 \([1, n]\) 作为下标,或者访问 \(n + 1\) 的时候数组越界导致运行时错误。

1
2
3
4
5
6
const int N = 5e5 + 5;
int n, a[N];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
}

变长数组 (Variable Length Array)

如果数组开在函数内,那么大小可以是变量。

1
2
3
4
5
6
int main() {
    int n;
    cin >> n;
    int a[n];
    for (int i = 0; i < n; i++) cin >> a[i];
}

MSVC 不支持该语法

具体请见参考资料

使用 STL

局部的动态数组可以考虑使用 STL 中的 vector,能够完成类似 Python list 的功能,在 下一节 我们将会讨论。

new 和 malloc

不建议使用 new 或者 malloc 申请数组,除非你知道你在干什么。

  • 不熟悉的话很容易写错,比如申请数组写成 new int (n) 而不是 new int [n]
  • 在算法题的语境下,大多数时候不需要使用动态申请数组,或者有更方便的方案。
  • 如果确实需要使用的话,在内存浪费不严重的前提下可以考虑不管 delete 或者 free,交给操作系统就好。

  1. 如果你读过“虎书”《现代编译原理:C语言描述》,你可以发现在这种目的下,作者甚至推荐写一个玩具编译器也可以只申请内存而不释放。