写在一切之前

必须承认,一门上课不讲代码实现的理论课却有大量编程作业是非常不人道的。笔者无意为其辩解,但是以下是我们仍然保留这门课的编程作业的理由。

  • 写编程作业对于透彻理解算法非常有帮助。经常,我们上课理论上理解一个算法并不意味着我们真的理解了分析中的所有细节。我们举例来说:
    • 如果你正确实现了 Median of Medians 算法,你可能会感到震惊:这个算法进行了如此多次递归,竟然仍然是 \(O(n)\) 的!此时,你可能会去重温其证明,并再一次理解这里的主定理分析出来的含义。
    • 实现一个 DP 算法的程序,会要求你去想明白 DP 的边界条件(也即 induction basis),以及转移的限制条件。
  • 完成算法课的编程作业,可以提升你对于以后可能需要面对的 LeetCode 题目的自信。
    • 算法课上理解的算法难度可以达到通常意义上的 LeetCode Hard,我们希望你能在未来需要的时候将你算法课所学内容展示出来。
    • 这是一个重新学习程序设计与数据结构的契机。

尽管如此,本课程的 Programming 仍然主要是以自学为主。在之前的学期里,大家最初主要困惑于以下问题:

  • 本地没有环境,无法编译运行。
  • VS / VSCode / Code::Blocks… 或者编译器说一个看起来没问题的地方有问题。
  • 对 C++ 语言已经遗忘了,希望能有一定的参考。
  • 不知道正确的、合理的实现应该怎么写。
  • 提交 OJ 告诉我不正确,但是不知道怎么查错。

这些问题可能会消耗掉大量时间,甚至可能在前几次作业让人感到多选了一门实践课。几位算法课教授都认为这部分内容不应当属于仅有 3 学分的算法课,但是事实上很多问题是存在共性的。笔者希望能通过这个指南来做一点小小的补充,如果能起到帮助作用,那不胜荣幸。

本指南写作并不充分严谨,笔者力求的是提供较为偏向于实践的经验。

  • 因此,本文会尽可能绕开 C++ 课堂上学习的内容:迭代器,构造函数,模板等;需要的时候也以实际用法为主。